I work on python plugin for QGIS. In this plugin I have created a QTableWidget with 3 columns. These columns are QCheckbox, QTableWidgetItem and QComboBox. I would like to retrieve the values contained in these 3 columns. For the moment I managed to get the values of QComboBox and QTableWidgetItem but I can't seem to get the value of the QCheckBox.
liste = ['Carte 1','Carte 2','Carte 3','Carte 4','Carte 5','Carte 6']
combo_box_options = ["A4 Paysage","A4 Portrait", "A3 Paysage","A3 Portrait"]
self.dlg_format = Dialog_format()
self.dlg_format.tableWidget.setRowCount(len(liste))
for index in range(len(liste)):
item = QTableWidgetItem(liste[index])
self.dlg_format.tableWidget.setItem(index, 1, item)
self.dlg_format.tableWidget.setColumnWidth(0, 20)
self.dlg_format.tableWidget.setColumnWidth(1, 350)
combo = QComboBox()
for t in combo_box_options:
combo.addItem(t)
self.dlg_format.tableWidget.setCellWidget(index, 2, combo)
widget = QWidget()
checkbox = QCheckBox()
checkbox.setCheckState(Qt.Checked)
playout = QHBoxLayout(widget)
playout.addWidget(checkbox)
playout.setAlignment(Qt.AlignCenter)
playout.setContentsMargins(0,0,0,0)
widget.setLayout(playout)
self.dlg_format.tableWidget.setCellWidget(index, 0, widget)
self.dlg_format.show()
result = self.dlg_format.exec_()
if result:
for index in range(len(liste)):
text = self.dlg_format.tableWidget.item(index, 1).text()
format = self.dlg_format.tableWidget.cellWidget(index, 2).currentText()
check = self.dlg_format.tableWidget.cellWidget(index, 0).checkState() #Does not work
The QWidget is what is set as cell widget, not the checkbox, and that widget obviously has no checkState
attribute.
There are various possibilities for this scenario.
Make the checkbox an attribute of the widget:
widget = QWidget()
widget.checkbox = QCheckBox()
playout.addWidget(widget.checkbox)
# ...
check = self.dlg_format.tableWidget.cellWidget(index, 0).checkbox.checkState()
Make the checkbox's checkState
function a reference of the widget (note: no parentheses!) so that you can access it with the existing cellWidget(index, 0).checkState()
:
checkbox = QCheckBox()
widget.checkState = checkbox.checkState
Since all happens within the same scope (the function), you can totally ignore the cellWidget
and use a list of tuples that contains the widgets:
widgets = []
for index in range(len(liste)):
# ...
widgets.append((item, combo, checkbox))
# ...
if result:
for item, combo, checkbox in widgets:
text = item.text()
format = combo.currentText()
check = checkbox.checkState()
Note that:
checkState()
returns a Qt.CheckState
enum, which results in 2 (Qt.Checked
) for a checked box; if you need a boolean, use isChecked()
instead;enumerate
instead of range
, since you are iterating through the list items anyway: for index, text in enumerate(liste):
;combo.addItems(combo_box_options)
;for
loop;QHBoxLayout(widget)
there's no need for widget.setLayout(playout)
, as the widget argument on a layout already sets that layout on the widget;self.dlg_format
) is unrequired and keeps resources unnecessarily occupied: the dialog would be kept in memory even after it's closed, and would be then deleted and overwritten as soon as it's created again; just make it a local variable (dlg_format = Dialog_format()
);