0

我对 QCheckBox 有疑问。

我正在尝试将布尔变量连接到 QCheckBox 以便当我更改布尔变量时,QCheckBox 将被自动选中或取消选中。

我的问题类似于下面的问题,但方式相反。

问题:Python3 PyQt4 创建一个简单的 QCheckBox 并更改一个布尔变量

我只是将那个问题的一个解决方案复制到这里。

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class SelectionWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.ILCheck = False

        ILCheckbox = QCheckBox(self)
        ILCheckbox.setCheckState(Qt.Unchecked)

        ILCheckbox.stateChanged.connect(self.ILCheckbox_changed)

        MainLayout = QGridLayout()
        MainLayout.addWidget(ILCheckbox, 0, 0, 1, 1)

        self.setLayout(MainLayout)

    def ILCheckbox_changed(self, state):
        self.ILCheck = (state == Qt.Checked)

        print(self.ILCheck)


if __name__ == '__main__':
  app = QApplication(sys.argv)
  window = SelectionWindow()

  window.show()
  window.ILCheck = True
  sys.exit(app.exec_())

在这种情况下,一旦我将 ILCheck 设置为 True,就会检查 QCheckBox。

任何帮助,将不胜感激!!!

谢谢!!!!


更新:

我在我的项目中使用 MVC,上面的代码只是一个示例,显示了我需要什么。布尔值ILCheck将在其他地方使用,我不想ILCheckBox在我的模型中调用。

我希望如果我修改 , 的值ILCheckILCheckBox会做出正确的反应。


更新:

感谢您的所有回复和帮助。你所有的解决方案都很棒!!!我需要的方式更像是一个建模视图解决方案,以便我可以将建模部分与 gui 部分分开。当我想更新一些东西时,我只需要更新建模,而不需要关注 gui 的样子。我无法在 View Class 中设置此 Bool 属性,因此无法使用此解决方案。

我不确定 MVC 是否适合 PyQT。我有一个像下面这样有问题的解决方案。

from PyQt4 import QtGui, QtCore, uic
import sys
class CellList(QtGui.QStandardItemModel):
    def __init__(self, cells = [], parent = None):
        QtGui.QStandardItemModel.__init__(self, parent)
        self.__cells = cells
        self.add(cells)

    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            return QtCore.QString("Cell id List")
    def flags(self, index):
        return QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def add(self, cells):
        for i in xrange(0, len(cells)):
            item = QtGui.QStandardItem('Cell %s' % cells[i][0])
            if (cells[i][1]):
                item.setCheckState(QtCore.Qt.Checked)
            else:
                item.setCheckState(QtCore.Qt.Unchecked)

            item.setCheckable(True)
            self.appendRow(item)
    def update(self, cells = None):
        # TODO: Making this working with out clean all old Cell
        self.clear()
        if cells is None: 
            cells = self.__cells
        else:
            print "hi"
            self.__cells = cells
        print cells
        self.add(cells)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    listView = QtGui.QListView()
    listView.show()

    data = [[85, True], (105, True), (123, False)]
    model = CellList(data)
    listView.setModel(model)

    data[0][1] = False
    model.update(data)

    sys.exit(app.exec_())

这个解决方案有一个问题,我无法解决。我认为只有视图才能设置模型。我不确定是否可以将模型设置为单个QCheckBox. .

4

3 回答 3

3

正如 Avaris 在他/她的回答中所表明的那样,模拟运算符的重载=是解决问题的良好开端。但是仍然存在将代码添加到SelectionWindow类中的问题。

但是由于我们使用的是Qt,让我们实现一个自定义QObject来表示我们的“智能”布尔变量,该变量将在更改其值时发出信号。

class SmartBool(QObject):

    valueChanged = pyqtSignal(bool)         # Signal to be emitted when value changes.

    def __init__(self):
        super(SmartBool, self).__init__()   # Call QObject contructor.
        self.__value = False                # False initialized by default.

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, value):
        if self.__value != value:
            self.valueChanged.emit(value)   # If value change emit signal.
            self.__value = value

现在您的代码只需要几处更改:

替换行:

self.ILCheck = False

经过:

self.ILCheck = SmartBool()

并连接信号和插槽,将线添加到 _ _ init _ _ 在上面的线之后的某个位置。重要的是,您没有绑定在SelectionWindow课堂内建立连接

self.connect(self.ILCheck, SIGNAL("valueChanged(bool)"), ILCheckbox, SLOT("setChecked(bool)"))

为了测试结果,只需添加:

 window.ILCheck.value = True

到您的“主要”,您将在下次运行示例时看到选中的复选框。

出于安全原因,完整的代码示例被添加到末尾

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class SmartBool(QObject):

    valueChanged = pyqtSignal(bool)         # Signal to be emitted when value changes.

    def __init__(self, value=False):
        super(SmartBool, self).__init__()   # Call QObject contructor.
        self.__value = value                # False initialized by default.

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, value):
        if self.__value != value:
            self.valueChanged.emit(value)   # If value change emit signal.
            self.__value = value


class SelectionWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ILCheck = SmartBool()          # Your steroides bool variable.
        ILCheckbox = QCheckBox(self)
        self.connect(self.ILCheck, SIGNAL("valueChanged(bool)"), ILCheckbox, SLOT("setChecked(bool)"))
        ILCheckbox.setCheckState(Qt.Unchecked)
        ILCheckbox.stateChanged.connect(self.ILCheckbox_changed)
        MainLayout = QGridLayout()
        MainLayout.addWidget(ILCheckbox, 0, 0, 1, 1)
        self.setLayout(MainLayout)

    def ILCheckbox_changed(self, state):
        self.ILCheck = (state == Qt.Checked)
        print(self.ILCheck)


if __name__ == '__main__':
  app = QApplication(sys.argv)
  window = SelectionWindow()
  window.show()
  window.ILCheck.value = True
  sys.exit(app.exec_())
于 2014-06-10T17:59:38.563 回答
1

property是定义在分配/访问时执行额外工作的变量的方法。下面是为此目的而修改的代码。它更改ILCheck为一个属性,因此它也会在分配时更新复选框。适当的错误检查.setter被忽略了,但很可能需要。

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class SelectionWindow(QWidget):
    def __init__(self, parent=None):
        super(SelectionWindow, self).__init__(parent)

        self._ILCheck = False

        self.ILCheckbox = QCheckBox(self)
        self.ILCheckbox.setCheckState(Qt.Unchecked)

        self.ILCheckbox.stateChanged.connect(self.ILCheckbox_changed)

        MainLayout = QGridLayout()
        MainLayout.addWidget(self.ILCheckbox, 0, 0, 1, 1)

        self.setLayout(MainLayout)

    def ILCheckbox_changed(self, state):
        self._ILCheck = (state == Qt.Checked)

        print(self.ILCheck)

    @property
    def ILCheck(self):
        return self._ILCheck

    @ILCheck.setter
    def ILCheck(self, value):
        self._ILCheck = value
        self.ILCheckbox.setChecked(value)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = SelectionWindow()

    window.show()
    window.ILCheck = True
    sys.exit(app.exec_())
于 2014-06-06T16:11:11.280 回答
0

只需ILCheckbox.setCheckState(Qt.Checked)在调用 ILCheck 后使用。

您在这里不需要信号,因为您可以直接调用插槽。

如果你想多次使用这个特性,你应该考虑编写一个改变状态self.ILCheck并发出信号的设置器。

澄清后编辑:

于 2014-06-05T22:10:13.227 回答