Python Forum
[PyQt] PyQt4 handle dynamic checkbox click
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] PyQt4 handle dynamic checkbox click
#1
I'm working on a screen that displays a QTableWidget. Each row in the table has a string 'Part Role Name' followed by 5 checkboxes. The number of rows in the table change based on Json results returned from a web API call. So the table is sized and the rows added dynamically. I have a class that represents each table row. I'm having trouble wiring up a given checkbox to its corresponding field for the statechanged event. I can tell the event is firing and what state it is changing to, I just don't know which field to update. Here is my Python class:

from PyQt4 import QtCore, QtGui

class PartRoleShadow(object):
    """Part role shadow settings for rendering"""

    def __init__(self, name, caster, catcher, excluded, hidden, render):
        self.part_role_name = name
        self.shadow_caster = caster
        self.shadow_catcher = catcher
        self.excluded = excluded
        self.hidden = hidden
        self.render = render

    def _widget(self, flag):
        cell_widget = QtGui.QWidget()
        chk_bx = QtGui.QCheckBox()
        chk_val = QtCore.Qt.Unchecked
        if flag:
            chk_val = QtCore.Qt.Checked
        chk_bx.setCheckState(chk_val)
        chk_bx.stateChanged.connect(self.set_value)
        lay_out = QtGui.QHBoxLayout(cell_widget)
        lay_out.addWidget(chk_bx)
        lay_out.setAlignment(QtCore.Qt.AlignCenter)
        lay_out.setContentsMargins(0, 0, 0, 0)
        cell_widget.setLayout(lay_out)
        return cell_widget

    def set_value(self, state):
        if state == QtCore.Qt.Checked:
            bvalue = True
        else:
            bvalue = False
        print("State Changed. It is now " + str(bvalue))
        print(self)

    def get_shadow_caster_checkbox_widget(self):
        return self._widget(self.shadow_caster)

    def get_shadow_catcher_checkbox_widget(self):
        return self._widget(self.shadow_catcher)

    def get_excluded_checkbox_widget(self):
        return self._widget(self.excluded)

    def get_hidden_checkbox_widget(self):
        return self._widget(self.hidden)

    def get_render_checkbox_widget(self):
        return self._widget(self.render)
Print results from checking/unchecking a box:

State Changed. It is now True
<PartRoleShadow.PartRoleShadow object at 0x038180B0>
State Changed. It is now False
<PartRoleShadow.PartRoleShadow object at 0x038180B0>
Reply
#2
I don't know if this is the best approach, but it works. I stripped the _widget method out of the class and created a new class called CheckBox. I then made each of the boolean properties of the PartRoleShadow class instances of CheckBox, like so:

class PartRoleShadow(object):
    """Part role shadow settings for rendering"""

    def __init__(self, name, caster, catcher, excluded, hidden, render):
        self.part_role_name = name
        self.shadow_caster = cb.CheckBox(name, "caster", caster)
        self.shadow_catcher = cb.CheckBox(name, "catcher", catcher)
        self.excluded = cb.CheckBox(name, "excluded", excluded)
        self.hidden = cb.CheckBox(name, "hidden", hidden)
        self.render = cb.CheckBox(name, "render", render)
I extended the definition of the checkbox class to include the row name and column name. This allows me to easily reference the cell to retrieve the value.

class CheckBox(QtGui.QWidget):
    def __init__(self, rowname, colname, flag=False):
        QtGui.QWidget.__init__(self)
        chk_bx = QtGui.QCheckBox()
        chk_val = QtCore.Qt.Unchecked
        if flag:
            chk_val = QtCore.Qt.Checked
        chk_bx.setCheckState(chk_val)
        chk_bx.stateChanged.connect(self.item_clicked)
        chk_bx.setObjectName(rowname + colname)
        lay_out = QtGui.QHBoxLayout(self)
        lay_out.addWidget(chk_bx)
        lay_out.setAlignment(QtCore.Qt.AlignCenter)
        lay_out.setContentsMargins(0, 0, 0, 0)
        self.setLayout(lay_out)
An example of retrieving a checkbox value from a cell:

        # retrieve checkbox values for each row
        for r in range(widget.rowCount()):
            # get part role name for cell lookup key
            name = widget.item(r, 0).text()
            # get the checkbox by constructing a lookup key for the row & column
            item = widget.findChild(QtGui.QCheckBox, name + "caster")
            print(item.checkState())
If anybody has a different approach, I would be happy to see it.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyQt] choose checkbox devilonline 1 1,282 Feb-17-2023, 01:23 PM
Last Post: Axel_Erfurt
  [Tkinter] Dynamic checkbox treeview issue OogieM 8 4,911 Mar-20-2022, 02:10 PM
Last Post: OogieM
  tkinter change the text of the checkbox zazas321 1 3,832 Sep-17-2021, 06:19 AM
Last Post: zazas321
  How to get the value of a checkbox scratchmyhead 4 3,037 May-14-2020, 02:56 PM
Last Post: scratchmyhead
  Tkinter checkbox value scratchmyhead 5 3,683 May-09-2020, 11:44 PM
Last Post: menator01
  TreeviewWith CheckBox issac_n 1 7,743 Mar-08-2020, 06:51 AM
Last Post: shamnadinn
  Tkinter Checkbox niro_one 1 2,346 Jan-13-2020, 11:31 AM
Last Post: joe_momma
  [Tkinter] Unable to create checkbox and select at run time tej7gandhi 5 4,656 May-05-2019, 04:57 PM
Last Post: tej7gandhi
  [PyQt] PyQt4 dynamic QComboBox littleGreenDude 4 5,679 Jan-02-2019, 07:22 PM
Last Post: littleGreenDude
  PyQt4 installation frustration littleGreenDude 4 4,540 Dec-27-2018, 04:29 PM
Last Post: littleGreenDude

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020