繁体   English   中英

Python2 PyQt4将布尔变量连接到QCheckBox项

[英]Python2 PyQt4 Connect a bool Variable to a QCheckBox item

我的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

我希望如果我修改ILCheck的值, ILCheckBox会正确响应。


更新:

感谢您的所有答复和帮助。 您所有的解决方案都很棒!!! 我需要的方式更像是Modeling-View解决方案,以便我可以将建模部分与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

正如Avaris在他/她的答案中所显示的那样,模拟operator =的重载是解决问题的良好起点。 但是仍然存在将代码添加到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_())

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_())

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

由于您可以直接调用插槽,因此您无需在此处发出信号。

如果要多次使用此功能,则应考虑编写一个setter来更改self.ILCheck的状态并发出信号。

澄清后进行编辑:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM