如何访问动态创建的 tablewidget?

Posted

技术标签:

【中文标题】如何访问动态创建的 tablewidget?【英文标题】:How to access dynamically created tablewidget? 【发布时间】:2021-01-12 12:20:34 【问题描述】:

在我的项目中,我从数据库中为每个产品名称创建了三个项目:QCombobox、QLabel、QCheckbox(将自身名称作为文本提供给 QLabel)。之后,我在 QTableWidget 中列出这些项目。我想做的事情是到达选定的 QCheckbox 的行的 QLabel 的文本和同一行的 QCombobox 的当前索引。

我可以到达 QTableWidget 的选定 QCheckbox,但我不知道如何到达 QCheckbox 行的其他项目。

函数 current_index 应该返回 QLabel 的文本和 QCheckbox 的文本。

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 在我的场景中,当按钮单击时,它应该返回选定的 QCheckbox(ARG.YI.2002 和 ARG.YI.2021)QLabel 的文本**(ARG.YI.2002 的“KREMA”和 ARG.YI 的“CEVİZİÇİEXTRA”。 2021) ** 和 QCombobox 的当前文本 (ARG.YI.2002 为“5 GÜN”,ARG.YI.2021 为“1 GÜN”)

【问题讨论】:

你能更好地解释一下你想从current_index得到什么吗?考虑到“当前索引”的概念不是被检查项的索引,并且通过您的函数,您还将获得 any 已检查的 QCheckBox。 其实我想根据勾选的QCheckbox的行获取QLabel的文字和QCombobox的文字。 【参考方案1】:

最简单的方法是为小部件创建一个列表,并使用添加为元组的每一行小部件来填充它。

请注意,我稍微更改了for 循环以使其更具可读性,并且我还将setRowCount()setColumnCount() 移到了它之外,因为在循环中连续设置它们具有相同的值是没有用的。

我还更改了小部件引用,它们现在是局部变量而不是实例属性:使用循环时,为每个循环覆盖实例属性没有多大意义,因为它总是会丢失下一次迭代。

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())

请注意,以上是最基本的(可能更 Pythonic)的可能性;您可以在没有列表的情况下使用 QTableWidget 提供的功能来做同样的事情,这更“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())

【讨论】:

我非常感谢这个解决方案。我痴迷于从 tablewidget 获取这些文本,我想不出用不同的方法来获取它们。它运行顺利。 @MelikşahÖztürk 无论如何你都可以,没有必要使用findChildren:就像Qt中几乎所有以set*开头的函数一样,可能有一个“getter”返回当前状态/对象/值集:在这种情况下,cellWidget()。查看更新。 编辑运行起来更令人愉快,正如你所说,它更 Qt-onic 和我所寻找的更多:) 再次感谢你。

以上是关于如何访问动态创建的 tablewidget?的主要内容,如果未能解决你的问题,请参考以下文章

创建和访问类对象的动态数组

oracle 的存储过程中 动态的创建一张表 然后插入一个变量到这个表中,表能动态的创建但是变量不能插入进去

如何在 tableWidget PyQT 中添加一行?

如何创建自己电脑开机动态密码

怎样在table下面动态增加一行

如何使用协议缓冲区创建动态消息?