Eliazar
Eliazar

Reputation: 380

How to iterate a column in QTableWidget and check if a check box is checked?

How can I iterate one column in QTableWidget and check if a checkbox is checked?

enter image description here

When I clicked the button in the left, I want to iterate the column in the picture and check if a checkbox is checked.

As of now, I've tried this function but the function only return 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

This is the code to use in order to reproduce this problem (I already removed those unnecessary parts of the code):

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

I hope you can help me with this problem

Upvotes: 2

Views: 1475

Answers (1)

musicamante
musicamante

Reputation: 48509

A "cell widget" is a QWidget that is added to an index of the view, as much as it's done using setIndexWidget() for any QAbstractItemView. It can be any widget, a checkbox, a combo, a custom widget, or even another item view.

If the requirement is to have checkable items, there's no need for that, since Qt models already provide the feature, which you're already using when doing item.setCheckState().

So, the solution is much simpler: look for the item(), and then verify the state:

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

Remember that:

  • QTableWidget can have empty cells, which are items for which no QTableWidgetItem has been set yet and no data has been inserted by the user (even if their index exist), that's why I had to check if the item is not None;
  • don't confuse item(row, col) with itemAt(x, y), which is based on pixel coordinates on the view;
  • if an item has no checkState explicitly set, its value is also None.
  • don't use booleans to set and verify the states, because Qt check states are tristate: Unchecked (0), PartiallyChecked (1) and Checked (2); by default their mouse behavior is boolean, but you have to consiser this before doing any "basic" action like you'd do with a basic bool (for QCheckBox, though, as for any button, you can use isChecked() and setChecked(), which are normal boolean based functions); this means that if you try to do setCheckState(True), the result will be a partially checked item, since for python True is the same as 1 (so, in Qt terms, PartiallyChecked): if you want to set a fully checked state, you should to do setCheckState(Qt.Checked);

Upvotes: 1

Related Questions