Issue
How can I iterate one column in QTableWidget
and check if a checkbox is checked?
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
Solution
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)
withitemAt(x, y)
, which is based on pixel coordinates on the view; - if an item has no
checkState
explicitly set, its value is alsoNone
. - don't use booleans to set and verify the states, because Qt check states are tristate:
Unchecked
(0),PartiallyChecked
(1) andChecked
(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 basicbool
(for QCheckBox, though, as for any button, you can useisChecked()
andsetChecked()
, which are normal boolean based functions); this means that if you try to dosetCheckState(True)
, the result will be a partially checked item, since for pythonTrue
is the same as1
(so, in Qt terms,PartiallyChecked
): if you want to set a fully checked state, you should to dosetCheckState(Qt.Checked)
;
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.