【问题标题】:How to iterate a column in QTableWidget and check if a check box is checked?如何迭代 QTableWidget 中的列并检查是否选中了复选框?
【发布时间】:2021-11-09 14:15:37
【问题描述】:

如何迭代QTableWidget 中的一列并检查是否选中了复选框?

当我单击左侧的按钮时,我想迭代图片中的列并检查是否选中了复选框。

到目前为止,我已经尝试过这个函数,但是这个函数只返回None

def checkBoxcheck(self):
    print("checkBoxcheck started")
    for row in range(self.rowCount()):
        print(self.cellWidget(1, 1))
        if not self.cellWidget(1, 1) is None:
            if self.cellWidget(row, 1).isChecked():
                #others to do

这是用于重现此问题的代码(我已经删除了代码中那些不必要的部分):

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QTableWidget, \
                        QTableWidgetItem, QVBoxLayout, QHBoxLayout
from PyQt5.QtCore import Qt
from PyQt5 import QtCore, QtWidgets
import sys

class TableWidget(QTableWidget):
    def __init__(self):
        super().__init__(10, 3)
        self.verticalHeader().setDefaultSectionSize(10)
        self.horizontalHeader().setDefaultSectionSize(200)

        for rows in range(self.rowCount()):
            item = QtWidgets.QTableWidgetItem()
            item.setCheckState(QtCore.Qt.Unchecked)
            self.setItem(rows, 1, item)

    def checkBoxcheck(self):
        print("checkBoxcheck started")
        for row in range(self.rowCount()):
            print(self.cellWidget(1, 1))
            if not self.cellWidget(1, 1) is None:
                if self.cellWidget(row, 1).isChecked():
                    #others to do
                    pass


class AppDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(700, 500)

        mainLayout = QHBoxLayout()
        table = TableWidget()
        mainLayout.addWidget(table)
        buttonLayout = QVBoxLayout()

        button_new = QPushButton('Check if checked')
        button_new.clicked.connect(table.checkBoxcheck)
        buttonLayout.addWidget(button_new)

        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

def app():
    app = QApplication(sys.argv)
    demo = AppDemo()
    demo.show()
    sys.exit(app.exec_())

app()

希望你能帮我解决这个问题

【问题讨论】:

  • 为了清楚起见,除了我的回答中的解释之外,在您的循环中,您总是检查(1, 1) 的项目,这显然是没有意义的。
  • 好的,我刚刚注意到它一个错字,您重复了再次,并且您已经发布了另一个问题。所以: 1. 使用for循环的变量时请多加注意; 2. 更仔细地遵循给你的建议; 3. 如果您只需要添加细节或代码,请不要创建新问题,使用edit链接并修改帖子!

标签: python pyqt pyqt5 qtablewidget


【解决方案1】:

“单元格小部件”是添加到视图索引中的 QWidget,就像对任何 QAbstractItemView 使用 setIndexWidget() 所做的一样。它可以是任何小部件、复选框、组合、自定义小部件,甚至是另一个项目视图。

如果要求有可检查的项目,则没有必要这样做,因为 Qt 模型已经提供了该功能,而您在执行 item.setCheckState() 时已经在使用该功能。

所以,解决方法要简单得多:查找item(),然后验证状态:

for row in range(self.rowCount()):
    item = self.item(row, 1)
    if item is not None and item.checkState():
        # ...

记住:

  • QTableWidget 可以有 empty 单元格,这些单元格还没有设置 QTableWidgetItem 并且用户没有插入数据(即使它们的索引存在),这就是我必须检查的原因如果该项目不是无;
  • 不要将item(row, col)itemAt(x, y) 混淆,后者基于视图上的像素坐标;
  • 如果一个项目没有明确设置checkState,它的值也是None
  • 不要使用布尔值来设置和验证状态,因为Qt check states三态Unchecked (0)、PartiallyChecked (1) 和 Checked (2);默认情况下,它们的鼠标行为布尔值,但是在执行任何“基本”操作之前,您必须考虑这一点,就像使用基本的bool 一样(对于 QCheckBox,对于任何按钮,您可以使用isChecked()setChecked(),它们是普通的基于布尔函数);这意味着如果您尝试执行setCheckState(True),结果将是一个部分检查项,因为对于 python,True1 相同(所以,用 Qt 术语来说,PartiallyChecked):如果你想设置一个完全检查状态,你应该setCheckState(Qt.Checked);

【讨论】:

  • 感谢您的指导,对于重复我的另一个问题,我感到非常抱歉,但我会确保它永远不会再发生。
  • 他们不能做一个is True 检查来区分布尔值和整数吗?这只是要求错误。
  • @PatrickParker 1. 你必须记住 PyQt 是一个 binding,一个允许从 Python 使用 Qt(用 C++ 编写并编译)的系统; 2. PyQt 维护者在保持“中级API”尽可能与原始API 保持一致方面付出了很多努力; 3. Qt.CheckState 在设计上是三态的,提供中间检查将意味着产生性能问题; 4. 如果您不喜欢默认行为,只需通过检查Qt.CheckStateRole 继承并覆盖setData
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 2013-12-25
  • 2019-11-19
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
  • 2013-10-28
相关资源
最近更新 更多