Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
264 views
in Technique[技术] by (71.8m points)

python 3.x - How to access dynamically created tablewidget?

in my project I create three items : QCombobox,QLabel,QCheckbox from a database for every productname (which give name of itself to QLabel as text). After that I list those items in a QTableWidget. The thing I want to do is reaching selected QCheckbox's row's QLabel's text and current index of same row's QCombobox.

I can reach the selected QCheckboxs of QTableWidget but for further I don't know how to reach other items of QCheckbox's row.

The function is current_index which should return QLabel's text and QCheckbox's text.

import sys
from PyQt5 import QtWidgets,QtGui,QtCore
from PyQt5.QtWidgets import QLabel,QMainWindow,QApplication,QHeaderView,QTableWidgetItem,QMessageBox,QWidget
from uretim_sayfasi import Ui_MainWindow
import mysql.connector
global curs
global conn

conn=mysql.connector.connect(
    host="*****",
    user="****",
    password="*****",
    database="****"
    )
curs=conn.cursor()

class my_app(QMainWindow):
    def __init__(self):
        super(my_app, self).__init__()
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)
        self.list_products()
        self.ui.pushButton.clicked.connect(self.current_index)

    def list_products(self):
        curs.execute("SELECT productName,productId FROM products_list")
        products=curs.fetchall()
        curs.execute("SELECT shipmentTime FROM shipmentTime ORDER BY id")
        shipmentTime=curs.fetchall()
        c=0
        for i in products:
            self.ui.productlist.setRowCount(int(c + 1))
            self.ui.productlist.setColumnCount(3)
            e=QtWidgets.QLabel()
            e.setText(i[0])
            self.combo=QtWidgets.QComboBox()
            self.combo.addItems(j[0] for j in shipmentTime)
            self.checkbox=QtWidgets.QCheckBox(i[1])
            self.checkbox.setObjectName(i[1])
            self.ui.productlist.setCellWidget(c,2,self.combo)
            self.ui.productlist.setCellWidget(c,0,self.checkbox)
            self.ui.productlist.setCellWidget(c,1,e)

            c+=1


    def current_index(self):
        items=self.ui.productlist.findChildren(QtWidgets.QCheckBox)
        for i in items:
            if i.isChecked():
                n=i.objectName()
                print(n)

def app():
    app=QApplication(sys.argv)
    win=my_app()
    win.show()
    sys.exit(app.exec_())

app()

the result table In my senario, when pushbutton clicked, it should return selected QCheckbox's (ARG.YI.2002 and ARG.YI.2021) QLabel's text **("KREMA" for ARG.YI.2002 and "CEV?Z??? EXTRA" for ARG.YI.2021) ** and QCombobox's currenttext ("5 GüN" for ARG.YI.2002 and "1 GüN" for ARG.YI.2021).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The easiest way would be to create a list for the widgets, and populate it with each row of widgets added as a tuple.

Note that I slightly changed the for cycle to make it more readable, and I also moved the setRowCount() and setColumnCount() outside it, as continuously setting them in the cycle with the same values is useless.

I also changed the widget references, which are now local variables and not instance attribute anymore: when using loops it doesn't make a lot of sense to overwrite an instance attribute for every cycle, as it will always be lost on the next iteration.

class my_app(QMainWindow):
    def __init__(self):
        super(my_app, self).__init__()
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)
        self.list_products()
        self.ui.pushButton.clicked.connect(self.current_index)

        self.widgetList = []

    def list_products(self): 
        self.widgetList.clear()

        curs.execute("SELECT productName,productId FROM products_list")
        products=curs.fetchall()
        curs.execute("SELECT shipmentTime FROM shipmentTime ORDER BY id")
        shipmentTime=curs.fetchall()

        self.ui.productlist.setRowCount(len(products))
        self.ui.productlist.setColumnCount(3)

        for row, i in enumerate(products):
            label = QtWidgets.QLabel(i[0])
            combo = QtWidgets.QComboBox()
            combo.addItems(j[0] for j in shipmentTime)
            checkbox = QtWidgets.QCheckBox(i[1])
            checkbox.setObjectName(i[1])
            self.ui.productlist.setCellWidget(row, 0, checkbox)
            self.ui.productlist.setCellWidget(row, 1, label)
            self.ui.productlist.setCellWidget(row, 2, combo)

            self.widgetList.append((checkbox, label, combo))

    def current_index(self):
        for checkbox, label, combo in self.widgetList:
            if checkbox.isChecked():
                print(checkbox.objectName(), label.text(), combo.currentText())

Do note that the above is the most basic (and probably more pythonic) possibility; you can do the same without the list and using the functions provided by QTableWidget, which is more "Qt-onic" ;-) :

    def current_index(self):
        for row in range(self.ui.productlist.rowCount()):
            checkbox = self.ui.productlist.cellWidget(row, 0)
            if isinstance(QtWidgets.QCheckBox) and checkbox.isChecked():
                label = self.ui.productlist.cellWidget(row, 1)
                combo = self.ui.productlist.cellWidget(row, 2)
                print(checkbox.objectName(), label.text(), combo.currentText())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...