PyQt allign checkbox and put it in every row
Asked Answered
F

2

1

I'm trying to do this with the check-box. Sadly is made for C++ and any adaptation of the code for Python has the result this error: 'QWidget' object is not callable What I wanna to do is to add a check-box on each row, this is my code:

    pWidget = QWidget()
    pCheckbox = QCheckBox()
    pLayout = QVBoxLayout()
    pLayout.addWidget(pCheckbox)
    pLayout.setAlignment(Qt.AlignCenter)
    pLayout.setContentsMargins(0, 0 ,0, 0)
    pWidget.setLayout(pLayout)

    for char in accounts:
        for columnNumber in range(numberColumns):
            chkBoxItem = QTableWidgetItem()
            chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            chkBoxItem.setCheckState(Qt.Unchecked)
            self.mainAccountTable.insertRow(currentRowCount)
            self.mainAccountTable.setItem(currentRowCount, 0, pWidget(chkBoxItem))
            self.mainAccountTable.setItem(currentRowCount, 1, QTableWidgetItem(data[1]))

If I put pLayout = Layout() is saying that it isn't implemented in Python. So, how I can I add that checkbox aligned in center without the text area near for each row? Thanks in advance for any tips.

Later EDIT: moving the code inside the loop is working , but I can't control the checks:

for char in accounts:
        for columnNumber in range(numberColumns):
            pWidget = QWidget()
            pCheckbox = QCheckBox()
            pLayout = QVBoxLayout(pWidget)
            pLayout.addWidget(pCheckbox)
            pLayout.setAlignment(Qt.AlignCenter)
            pLayout.setContentsMargins(0, 0 ,0, 0)
            pWidget.setLayout(pLayout)
            #chkBoxItem = QTableWidgetItem()
            #chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            #chkBoxItem.setCheckState(Qt.Unchecked)
            self.mainAccountTable.insertRow(currentRowCount)
            self.mainAccountTable.setCellWidget(currentRowCount, 0, pWidget)

This is a screenshoot How can I know what I checked and build set list?

Faludi answered 8/9, 2015 at 12:39 Comment(0)
P
1

Here is an example from ekhumoro to find what is checked when it s being clicked :

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self, rows, columns):
        QtGui.QWidget.__init__(self)
        self.table = QtGui.QTableWidget(rows, columns, self)
        for column in range(columns):
            for row in range(rows):
                item = QtGui.QTableWidgetItem('Text%d' % row)
                if row % 2:
                    item.setFlags(QtCore.Qt.ItemIsUserCheckable |
                                  QtCore.Qt.ItemIsEnabled)
                    item.setCheckState(QtCore.Qt.Unchecked)
                self.table.setItem(row, column, item)
        self.table.itemClicked.connect(self.handleItemClicked)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.table)
        self._list = []

    def handleItemClicked(self, item):
        if item.checkState() == QtCore.Qt.Checked:
            print('"%s" Checked' % item.text())
            self._list.append(item.row())
            print(self._list)
        else:
            print('"%s" Clicked' % item.text())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window(6, 3)
    window.resize(350, 300)
    window.show()
    sys.exit(app.exec_())

But you can also iterate on your rows and use .findChild(type(QtGui.QCheckBox())).isChecked() on the proper column

such as :

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt

class Window(QtGui.QWidget):
    def __init__(self, rows, columns):
        QtGui.QWidget.__init__(self)
        self.table = QtGui.QTableWidget(rows, columns, self)
        for row in range(rows):
            qwidget = QtGui.QWidget()
            checkbox = QtGui.QCheckBox()
            checkbox.setCheckState(QtCore.Qt.Unchecked)
            qhboxlayout = QtGui.QHBoxLayout(qwidget)
            qhboxlayout.addWidget(checkbox)
            qhboxlayout.setAlignment(Qt.AlignCenter)
            qhboxlayout.setContentsMargins(0, 0, 0, 0)
            self.table.setCellWidget(row, 0, qwidget)
            self.table.setItem(row, 1, QtGui.QTableWidgetItem(str(row)))
        layout = QtGui.QVBoxLayout(self)
        self.button = QtGui.QPushButton()
        self.button.setObjectName("loadButton")
        layout.addWidget(self.table)
        layout.addWidget(self.button)
        self.button.clicked.connect(self.ButtonClicked)

    def ButtonClicked(self):
        checked_list = []
        for i in range(self.table.rowCount()):
            if self.table.cellWidget(i, 0).findChild(type(QtGui.QCheckBox())).isChecked():
                checked_list.append(self.table.item(i, 1).text())
        print checked_list


if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window(3, 2)
    window.resize(350, 300)
    window.show()
    sys.exit(app.exec_())
Pawl answered 8/9, 2015 at 13:26 Comment(8)
I saw that example, but it isn't the behavior that I need it. I need the solution for this falsinsoft.blogspot.ro/2013/11/…Faludi
You should use the findChild then by iterating on each row. This will allow you to find out what are the cell checked.Pawl
But how you adapt the "handle" method to check if is pushed or not? and if it's yes, to add it to the list.Faludi
Also if I check with that command, he will not check on the first column (where are the check-boxes) but from the next column :(Faludi
I added an example of the implementation.Pawl
@Alex. Thanks - but that's not the correct name :-)Possing
@Possing I'm so sorry. I just changed it. I have to say that I have this example saved on my computer. It s my quick starting point. Thank you so much for it!Pawl
@Pawl in ekhumoro example when I checked the box is automatically add it to the list of selected rows, but in your example I need to push the button (which is not what I want). Is there a way to do it like in ekhumoro example?Faludi
I
1

You could consider using the Qt Designer, so that you can:

  • Get your desired layout visually with immediate feedback
  • Get to see the actual code generated from it and spot what you were missing

After you get your desired window (i.e. the file with a .ui extension), you can use the pyuic5[1] utility, which will generate a Python file from the UI file. From the man page

pyuic5 - compile Qt5 user interfaces to Python code

Steps

Simple steps with example

Create and Save the UI

You should use the Qt Designer and save the .ui file.

Generate Python code from the UI file

If your .ui file is named mainwindow.ui then you can use the command:

pyuic5 mainwindow.ui -o mainwindow.py

Update your Python code

Get your Python code to use the generated Python-based UI file.

from PyQt5.QtWidgets import QMainWindow

from mainwindow import Ui_MainWindow   # <<--- important

# Set up the user interface from Designer.
win = QMainWindow()
gui = Ui_MainWindow()
gui.setupUi(win)

As you can see above, you need to import the class representing the UI from the Python module that was generated, in our case being the mainwindow.py file from the command in the prev. step.

The class is automatically prefixed with Ui_ by the utility. You then instantiate a QMainWindow and the generated class and use Qt's built-in method setupUi for it to incorporate all the widgets, etc.

Important: Every time you update your window in Qt Designer, you'll need to repeat step #2. Considering the amount of time saved by using the Designer directly, this shouldn't be a problem.

Note: You can use the generated mainwindow.py file to read the code and see how the desired layout was achieved. This should be useful if you really do not want to continue using this approach.

[1] The pyuic5 command is found within the pyqt5-dev-tools package, so a sudo apt-get install pyqt5-dev-tools should do it.

Ionone answered 8/9, 2015 at 13:14 Comment(0)
P
1

Here is an example from ekhumoro to find what is checked when it s being clicked :

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self, rows, columns):
        QtGui.QWidget.__init__(self)
        self.table = QtGui.QTableWidget(rows, columns, self)
        for column in range(columns):
            for row in range(rows):
                item = QtGui.QTableWidgetItem('Text%d' % row)
                if row % 2:
                    item.setFlags(QtCore.Qt.ItemIsUserCheckable |
                                  QtCore.Qt.ItemIsEnabled)
                    item.setCheckState(QtCore.Qt.Unchecked)
                self.table.setItem(row, column, item)
        self.table.itemClicked.connect(self.handleItemClicked)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.table)
        self._list = []

    def handleItemClicked(self, item):
        if item.checkState() == QtCore.Qt.Checked:
            print('"%s" Checked' % item.text())
            self._list.append(item.row())
            print(self._list)
        else:
            print('"%s" Clicked' % item.text())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window(6, 3)
    window.resize(350, 300)
    window.show()
    sys.exit(app.exec_())

But you can also iterate on your rows and use .findChild(type(QtGui.QCheckBox())).isChecked() on the proper column

such as :

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt

class Window(QtGui.QWidget):
    def __init__(self, rows, columns):
        QtGui.QWidget.__init__(self)
        self.table = QtGui.QTableWidget(rows, columns, self)
        for row in range(rows):
            qwidget = QtGui.QWidget()
            checkbox = QtGui.QCheckBox()
            checkbox.setCheckState(QtCore.Qt.Unchecked)
            qhboxlayout = QtGui.QHBoxLayout(qwidget)
            qhboxlayout.addWidget(checkbox)
            qhboxlayout.setAlignment(Qt.AlignCenter)
            qhboxlayout.setContentsMargins(0, 0, 0, 0)
            self.table.setCellWidget(row, 0, qwidget)
            self.table.setItem(row, 1, QtGui.QTableWidgetItem(str(row)))
        layout = QtGui.QVBoxLayout(self)
        self.button = QtGui.QPushButton()
        self.button.setObjectName("loadButton")
        layout.addWidget(self.table)
        layout.addWidget(self.button)
        self.button.clicked.connect(self.ButtonClicked)

    def ButtonClicked(self):
        checked_list = []
        for i in range(self.table.rowCount()):
            if self.table.cellWidget(i, 0).findChild(type(QtGui.QCheckBox())).isChecked():
                checked_list.append(self.table.item(i, 1).text())
        print checked_list


if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window(3, 2)
    window.resize(350, 300)
    window.show()
    sys.exit(app.exec_())
Pawl answered 8/9, 2015 at 13:26 Comment(8)
I saw that example, but it isn't the behavior that I need it. I need the solution for this falsinsoft.blogspot.ro/2013/11/…Faludi
You should use the findChild then by iterating on each row. This will allow you to find out what are the cell checked.Pawl
But how you adapt the "handle" method to check if is pushed or not? and if it's yes, to add it to the list.Faludi
Also if I check with that command, he will not check on the first column (where are the check-boxes) but from the next column :(Faludi
I added an example of the implementation.Pawl
@Alex. Thanks - but that's not the correct name :-)Possing
@Possing I'm so sorry. I just changed it. I have to say that I have this example saved on my computer. It s my quick starting point. Thank you so much for it!Pawl
@Pawl in ekhumoro example when I checked the box is automatically add it to the list of selected rows, but in your example I need to push the button (which is not what I want). Is there a way to do it like in ekhumoro example?Faludi

© 2022 - 2024 — McMap. All rights reserved.