Окно с QCheckBox
Имеется окно с QCheckBox (chech.py). По умолчанию выставлены три галки checkbox (п.1, п2, п3) и четвертая галка checkbox ("Выбрать все папки") – пока первые три checkbox имеют статус True. Если снять одну из трех галок checkbox (п.1, п2, п3), то четвертая галка checkbox ("Выбрать все папки") – снимается (скриншот №1).
Трудности: Но если снять четвертую галку checkbox ("Выбрать все папки") – первые три галки checkbox (п.1, п2, п3) остаются (скриншот №2).
Вопрос: Как сделать, что бы при снятии четвертой галки checkbox ("Выбрать все папки") – первые три галки checkbox (п.1, п2, п3) тоже снимались.
P.S. предложения по улучшению кода приветствуются.
chech.py
import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
from PyQt5.QtWidgets import (QWidget, QCheckBox, QMessageBox, )
from PyQt5.QtCore import (pyqtSlot, )
class MessageBox(QtWidgets.QMessageBox, QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Внимание!")
self.setIcon(self.Critical)
self.addButton(QtWidgets.QPushButton('Удалить'), QtWidgets.QMessageBox.YesRole)
self.addButton(QtWidgets.QPushButton('Отмена'), QtWidgets.QMessageBox.NoRole)
self.addCheckBox(self)
currentClick = self.exec_()
if currentClick == 0:
print(' нажата кнопка = Удалить')
print()
if self.check1.isChecked() == False and \
self.check2.isChecked() == False and \
self.check3.isChecked() == False:
self.not_del()
else:
if self.check1.isChecked() == True:
print(' значение CheckBox (1. ) =', self.check1.isChecked())
self.del_Doc()
if self.check2.isChecked() == True:
print(' значение CheckBox (2. ) =', self.check2.isChecked())
self.del_Otv()
if self.check3.isChecked() == True:
print(' значение CheckBox (3. ) =', self.check3.isChecked())
self.del_Im()
self.message()
if currentClick == 1:
print(' нажата кнопка = Отмена')
def addCheckBox(self, parentItem):
self.l = QtWidgets.QVBoxLayout()
lb1 = QtWidgets.QLabel("Файлы удалятся безвозвратно. \n Вы уверены?", self)
lb1.setGeometry(60, 15, 300, 40)
lb2 = QtWidgets.QLabel('Следующие данные будут удалены:', self)
lb2.setGeometry(20, 60, 350, 20)
self._toggle = True
self.check1 = QCheckBox('1.', self)
self.check1.setGeometry(20, 85, 200, 20)
self.check1.setChecked(self._toggle)
self.check2 = QCheckBox('2.', self)
self.check2.setGeometry(20, 105, 200, 20)
self.check2.setChecked(self._toggle)
self.check3 = QCheckBox('3.', self)
self.check3.setGeometry(20, 125, 200, 20)
self.check3.setChecked(self._toggle)
self.check = QCheckBox('Выбрать все папки', self)
self.check.setGeometry(20, 155, 200, 20)
self.check.setChecked(self._toggle)
self.check1.clicked.connect(self.chec_toggle)
self.check2.clicked.connect(self.chec_toggle)
self.check3.clicked.connect(self.chec_toggle)
self.check.clicked.connect(self.chec_toggle)
self.setLayout(self.l)
@pyqtSlot()
def chec_toggle(self):
if self.sender() == self.check:
if self._toggle == True:
self.check1.setChecked(self._toggle)
self.check2.setChecked(self._toggle)
self.check3.setChecked(self._toggle)
else:
self.check1.setChecked(not self._toggle)
self.check2.setChecked(not self._toggle)
self.check3.setChecked(not self._toggle)
self.check.setChecked(not self._toggle)
elif self.sender() in (self.check1, self.check2, self.check3):
self.check.setChecked(not self._toggle)
def del_Doc(self): pass
def del_Otv(self): pass
def del_Im(self): pass
def not_del(self):
msgBox = QMessageBox(self)
msgBox.setIcon(QMessageBox.Information)
msgBox.setWindowTitle('Внимание!')
msgBox.setText(" Ни одна папка не выбрана! ")
msgBox.exec_()
def message(self):
msgBox0 = QMessageBox(self)
msgBox0.setIcon(QMessageBox.Information)
msgBox0.setText('Операция очистки завершена. ')
msgBox0.exec_()
def event(self, e):
result = QtWidgets.QMessageBox.event(self, e)
self.setMinimumWidth(0)
self.setMaximumWidth(16777215)
self.setMinimumHeight(0)
self.setMaximumHeight(16777215)
self.setSizePolicy(
QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Expanding
)
self.resize(250, 230)
return result
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = MessageBox()
sys.exit(app.exec_())
Ответы (1 шт):
Sorry, мне тяжело помочь вам с вашим кодом. Возможное решение может выглядеть примерно так:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class Custom_QGroupBox(QtWidgets.QGroupBox):
checkAllIfAny = True
def __init__(self, *args, **kwargs):
super(Custom_QGroupBox, self).__init__(*args, **kwargs)
self.setCheckable(True)
self.checkBoxes = []
self.toggled.connect(self.toggleCheckBoxes)
def addCheckBox(self, cb):
self.checkBoxes.append(cb)
cb.toggled.connect(self.update)
cb.destroyed.connect(lambda: self.removeCheckBox(cb))
def removeCheckBox(self, cb):
try:
self.checkBoxes.remove(cb)
cb.toggled.disconnect(self.update)
except:
pass
def allStates(self):
return [cb.isChecked() for cb in self.checkBoxes]
def toggleCheckBoxes(self):
if self.checkAllIfAny:
state = not all(self.allStates())
else:
state = not any(self.allStates())
for widget in self.children():
if not widget.isWidgetType():
continue
if not widget.testAttribute(QtCore.Qt.WA_ForceDisabled):
# восстановить включенное состояние, чтобы переопределить
# поведение setChecked(False) по умолчанию;
# предыдущие явные вызовы setEnabled(False) для целевого виджета
# будут игнорироваться
widget.setEnabled(True)
if widget in self.checkBoxes:
widget.setChecked(state)
def paintEvent(self, event):
opt = QtWidgets.QStyleOptionGroupBox()
self.initStyleOption(opt)
states = self.allStates()
if all(states):
# force the "checked" state
opt.state |= QtWidgets.QStyle.State_On
opt.state &= ~QtWidgets.QStyle.State_Off
else:
# force the "not checked" state
opt.state &= ~QtWidgets.QStyle.State_On
if any(states):
# force the "not unchecked" state and set the tristate mode
opt.state &= ~QtWidgets.QStyle.State_Off
opt.state |= QtWidgets.QStyle.State_NoChange
else:
# force the "unchecked" state
opt.state |= QtWidgets.QStyle.State_Off
painter = QtWidgets.QStylePainter(self)
painter.drawComplexControl(QtWidgets.QStyle.CC_GroupBox, opt)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.groupBox = Custom_QGroupBox('Все папки')
layout = QtWidgets.QGridLayout(self.groupBox)
num = 0
for c in range(1):
for r in range(3):
num += 1
cb = QtWidgets.QCheckBox(f' {num}.')
self.groupBox.addCheckBox(cb)
layout.addWidget(cb, r, c)
self.toolButton = QtWidgets.QToolButton()
self.toolButton.setIcon(QtGui.QIcon('head3.png'))
self.toolButton.setAutoRaise(True)
self.toolButton.setIconSize(QtCore.QSize(70, 70))
self.toolButton.setStyleSheet(
'background-color: green; border-radius: 35px;')
label_1 = QLabel("Файлы удалятся безвозвратно. Вы уверены?")
label_1.setWordWrap(True)
label_2 = QLabel('Следующие данные будут удалены:')
self.buttonDelete = QPushButton('Удалить')
self.buttonCancel = QPushButton('Отмена')
layoutH = QHBoxLayout()
layoutH.addStretch(1)
layoutH.addWidget(self.buttonDelete)
layoutH.addWidget(self.buttonCancel)
main_layout = QtWidgets.QGridLayout(self)
main_layout.addWidget(self.toolButton, 1, 1)
main_layout.addWidget(label_1, 1, 2)
main_layout.addWidget(label_2, 2, 1, 1, 2)
main_layout.addWidget(self.groupBox, 3, 1, 1, 2)
main_layout.addLayout(layoutH, 4, 1, 1, 2)
main_layout.setRowStretch(0, 1)
main_layout.setRowStretch(5, 1)
main_layout.setColumnStretch(0, 1)
main_layout.setColumnStretch(3, 1)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
w = MainWindow()
w.resize(370, 300)
w.show()
sys.exit(app.exec_())




