Python PyQt5-在表小部件的列中创建一个检查项,即使行数与spinbox不同

Python PyQt5-在表小部件的列中创建一个检查项,即使行数与spinbox不同,python,python-3.x,pyqt5,qt-designer,Python,Python 3.x,Pyqt5,Qt Designer,我是PyQt5的新手,我正在使用Qtdesigner开发一个接口 我从spinbox控制表格小部件的行数。但是,在更改行数时,我需要保留a列的check选项 我设法根据spinbox中的valueChanged更改了行数,但是我创建的用于创建检查的循环(不管行数如何)不起作用 from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow):

我是PyQt5的新手,我正在使用Qtdesigner开发一个接口

我从spinbox控制表格小部件的行数。但是,在更改行数时,我需要保留a列的check选项

我设法根据spinbox中的valueChanged更改了行数,但是我创建的用于创建检查的循环(不管行数如何)不起作用

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(519, 468)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
        self.spinBox.setGeometry(QtCore.QRect(80, 131, 41, 31))
        self.spinBox.setProperty("value", 2)
        self.spinBox.setObjectName("spinBox")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(160, 80, 341, 101))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(2)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        item.setFlags(QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
        item.setCheckState(QtCore.Qt.Checked)
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        item.setFlags(QtCore.Qt.ItemIsEnabled)
        item.setCheckState(QtCore.Qt.Checked)
        self.tableWidget.setItem(1, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 1, item)
        self.tableWidget.verticalHeader().setVisible(False)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 519, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.spinBox.valueChanged['int'].connect(self.tableWidget.setRowCount)

        for i in range(self.tableWidget.rowCount()):
            item = QtWidgets.QTableWidgetItem()
            item.setFlags(QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Checked)
            self.tableWidget.setItem(i, 0, item)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "d"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("MainWindow", "e"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "a"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "c"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setSortingEnabled(__sortingEnabled)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "d"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("MainWindow", "e"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "a"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "c"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setSortingEnabled(__sortingEnabled)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

首先,您似乎正在编辑
pyuic
生成的文件的输出,或者试图模拟其行为。无论如何,这是永远不应该做的事情

这些文件应保持原样,并且只能作为模块使用;要了解如何正确执行此操作,请阅读更多关于。如果您试图模仿它们的行为,那么您不应该这样做:处理pyuic文件的方式只被视为一个“解释层”,以便创建GUI对象并使它们可以从python访问。如果您是从代码构建GUI,那么只需对想要使用的QWidget(通常是QWidget、QDialog或QMainWindow)进行子类化即可

现在的问题是,无论何时调用…:

[it]将此表模型中的行数设置为行。如果小于rowCount(),则丢弃不需要的行中的数据

这显然意味着,如果您删除行,您将丢失该行中的所有项(包括它们完全可检查的事实)

要正确更新内容并添加可检查项,您需要使用动态删除或添加项的特定方法来执行此操作

在下一个示例中,我将演示如何正确实现这一点(并以更简单、更清晰的方式):

从PyQt5导入QtCore、QtWidgets
类MainWindow(QtWidgets.QMainWindow):
定义初始化(自):
super()。\uuuu init\uuuuu()
central=qtwidts.QWidget()
self.setCentralWidget(中央)
layout=qtwidts.QHBoxLayout(中心)
self.spin=qtwidts.QSpinBox()
layout.addWidget(self.spin)
self.table=QtWidgets.QTableWidget(2,2)
layout.addWidget(self.table)
self.table.verticalHeader().setVisible(False)
对于列,枚举中的标签(('a','c'):
header=QtWidgets.QTableWidgetItem(标签)
self.table.setHorizontalHeaderItem(列,标题)
如果列:
持续
对于范围内的行(self.table.rowCount()):
item=QtWidgets.QTableWidgetItem()
item.setFlags(item.flags()| QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Checked)
self.table.setItem(行、列、项)
self.spin.setValue(self.table.rowCount())
self.spin.valueChanged.connect(self.setRowCount)
def setRowCount(自身,计数):
如果count==self.table.rowCount():
返回
#如果行太多,请将其删除
而self.table.rowCount()>计数:
self.table.removeow(self.table.rowCount()-1)
#如果要添加行,请为其创建可检查项
而self.table.rowCount()
作为旁注,需要考虑以下几点:

  • 布局管理器应始终用于小部件,否则内容可能不可见或无法调整其位置
  • 您定义了两次
    重传
    ;我想这是编辑pyuic文件后留下的东西,但是,在任何情况下,用相同的名称重新定义函数都会导致覆盖它(除非每个函数都有一个唯一的decorator)

我可以看到图片中的复选框。你能准确地解释一下什么没有按预期工作吗?你的意思是当你添加一个新行时,它没有得到一个复选框吗?
from PyQt5 import QtCore, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        central = QtWidgets.QWidget()
        self.setCentralWidget(central)
        layout = QtWidgets.QHBoxLayout(central)
        self.spin = QtWidgets.QSpinBox()
        layout.addWidget(self.spin)
        self.table = QtWidgets.QTableWidget(2, 2)
        layout.addWidget(self.table)
        self.table.verticalHeader().setVisible(False)
        for col, label in enumerate(('a', 'c')):
            header = QtWidgets.QTableWidgetItem(label)
            self.table.setHorizontalHeaderItem(col, header)
            if col:
                continue
            for row in range(self.table.rowCount()):
                item = QtWidgets.QTableWidgetItem()
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
                item.setCheckState(QtCore.Qt.Checked)
                self.table.setItem(row, col, item)

        self.spin.setValue(self.table.rowCount())
        self.spin.valueChanged.connect(self.setRowCount)

    def setRowCount(self, count):
        if count == self.table.rowCount():
            return
        # if there are too many rows, remove them
        while self.table.rowCount() > count:
            self.table.removeRow(self.table.rowCount() - 1)
        # if rows are going to be added, create checkable items for them
        while self.table.rowCount() < count:
            row = self.table.rowCount()
            self.table.insertRow(row)
            item = QtWidgets.QTableWidgetItem()
            item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
            item.setCheckState(QtCore.Qt.Checked)
            self.table.setItem(row, 0, item)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    test = MainWindow()
    test.show()
    sys.exit(app.exec_())