python - PyQt5如何识别和抓取与其他组合框一起使用函数创建的QT组合框的数据
问题描述
我编写了一个脚本,它自动创建一个 QT“对象”,该对象由一个类别标签、一个带有可能属性的 combobox_1、一个按钮和一个用于列出所选属性的所有可用值的 combobox_2 组成。该脚本会根据需要创建尽可能多的这些“对象”。
对于每个“对象”,创建的按钮旨在获取 combobox_1 中的选定属性,并使用此信息从数据库中检索相关值并填充 combobx_2
现在我遇到的问题是,一旦组合框被创建,我就无法弄清楚如何引用它们。对于按钮,我使用 serve 函数来监听任何按钮的点击,这很好,但是我如何引用已经用函数创建的组合框。尽管它们都有不同的 setObjectName,但似乎没有引用该属性的方法,因此当我单击任何按钮时,它们都返回最后一个对象的组合框的值,而不是它们所附加的相关组合框的值.
这是前端脚本:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(709, 357)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.gridLayout_4 = QtWidgets.QGridLayout()
self.gridLayout_4.setObjectName("gridLayout_4")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_4.addItem(spacerItem, 1, 1, 1, 1)
self.VLayout_0 = QtWidgets.QVBoxLayout()
self.VLayout_0.setObjectName("VLayout_0")
self.HLayout_0 = QtWidgets.QHBoxLayout()
self.HLayout_0.setObjectName("HLayout_0")
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.HLayout_0.addItem(spacerItem1)
self.CB_L0 = QtWidgets.QComboBox(self.centralwidget)
self.CB_L0.setObjectName("CB_L0")
self.HLayout_0.addWidget(self.CB_L0)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setMaximumSize(QtCore.QSize(40, 16777215))
self.pushButton.setObjectName("pushButton")
self.HLayout_0.addWidget(self.pushButton)
spacerItem2 = QtWidgets.QSpacerItem(50, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.HLayout_0.addItem(spacerItem2)
self.VLayout_0.addLayout(self.HLayout_0)
spacerItem3 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.VLayout_0.addItem(spacerItem3)
self.gridLayout_4.addLayout(self.VLayout_0, 1, 0, 1, 1)
self.PB_create_cb = QtWidgets.QPushButton(self.centralwidget)
self.PB_create_cb.setObjectName("PB_create_cb")
self.gridLayout_4.addWidget(self.PB_create_cb, 0, 1, 1, 1)
self.gridLayout.addLayout(self.gridLayout_4, 0, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 709, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "search"))
self.PB_create_cb.setText(_translate("MainWindow", "Create dropdown"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
这是后端示例(创建两个“对象”):
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QAction, QTableWidget, QTableWidgetItem, QVBoxLayout, QMessageBox, QDialog, QLineEdit, QPushButton, QMenu, QSizePolicy, QLabel,QTreeWidget,QTreeWidgetItem
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton, QMessageBox)
import sys
from test3 import *
class Run_script(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Run_script, self).__init__(parent)
self.setupUi(self)
print("Run script initizalised")
self.PB_create_cb.clicked.connect(self.click_select)
def create_V_0_object(self,List_attributes):
V_list = []
for i,x in enumerate(List_attributes):
for k,v in x.items():
if type(v) == dict:
for k1,v1 in v.items():
if type(v) == dict:
self.HLayout_1 = QtWidgets.QHBoxLayout()
self.HLayout_1.setObjectName("H_layout_1")
self.VLayout_0 = QtWidgets.QVBoxLayout()
self.VLayout_0.setObjectName("V_L2"+k+str(i))
self.Attr_label = QtWidgets.QLabel(self.centralwidget)
self.Attr_label.setObjectName(k)
self.Attr_label.setText(k)
self.VLayout_0.addWidget(self.Attr_label)
self.attr_list = []
for k1,v1 in v.items():
self.attr_list.append(k1)
print("K1 is "+str(k1))
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setObjectName("CB_"+k)
self.comboBox.addItems(self.attr_list)
self.comboBox.setToolTip("CB_"+k)
self.VLayout_0.addWidget(self.comboBox)
self.comboBox1 = QtWidgets.QComboBox(self.centralwidget)
self.comboBox1.setObjectName("CB_l2_"+k)
self.comboBox1.setToolTip("CB_l2_"+k)
self.VLayout_0.addWidget(self.comboBox1)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
self.pushButton.setSizePolicy(sizePolicy)
self.pushButton.setMaximumSize(QtCore.QSize(40, 16777215))
PB_name = "PB_"+str(k)
self.pushButton.setObjectName(PB_name)
self.pushButton.setToolTip("Search " + str(PB_name))
self.pushButton.setText(PB_name)
self.pushButton.clicked.connect(self.buttonClicked)
self.HLayout_1.addLayout(self.VLayout_0)
self.HLayout_1.addWidget(self.pushButton)
else:
pass
V_list.append(self.HLayout_1)
return V_list
def buttonClicked(self):
sender = self.sender()
cat_l_0 = sender.text()
for i in range(self.VLayout_0.count()):
name = self.VLayout_0.itemAt(i).widget().objectName()
print("this is:",name)
def click_select(self):
self.selection = [{"Category1":{"Attr1": "test1","Attr2":"test2"}},{"Category2":{"Attr1":"test3","Attr2":"test4"}}]
self.v = self.create_V_0_object(self.selection)
self.create_horizontal_display(self.v)
def deleteItemsOfLayout(self,layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
self.deleteItemsOfLayout(item.layout())
def create_horizontal_display(self,vertical_layout_list):
self.deleteItemsOfLayout(self.HLayout_0)
for i,x in enumerate(vertical_layout_list):
self.HLayout_0.addLayout(x)
if __name__ == '__main__':
app = QApplication(sys.argv)
prog = Run_script()
prog.show()
sys.exit(app.exec_())
创建对象只需按“创建下拉菜单”按钮
解决方案
你有很多不好的做法:
在循环中创建的变量通常不会成为类的成员,因为它们是临时变量,所以不要使用它们,因为它们会被覆盖,因此在访问
self.VLayout_0
时总是会得到最后一个元素。另一个坏习惯是你想在一个地方做的所有事情,正如你所说的,“对象”除了数据之外都是相似的,所以你应该创建一个构建它的类,正如他们所说:分而治之。
您还有其他错误,但它们是次要的,更正上述您有以下内容:
from PyQt5 import QtCore, QtGui, QtWidgets
from test3 import Ui_MainWindow
class Widget(QtWidgets.QWidget):
clicked = QtCore.pyqtSignal()
def __init__(self, text, values, parent=None):
super(Widget, self).__init__(parent)
hlay = QtWidgets.QHBoxLayout(self)
vlay = QtWidgets.QVBoxLayout()
self.label = QtWidgets.QLabel(text)
self.combobox_1 = QtWidgets.QComboBox()
self.combobox_1.addItems(values.keys())
self.combobox_2 = QtWidgets.QComboBox()
vlay.addWidget(self.label)
vlay.addWidget(self.combobox_1)
vlay.addWidget(self.combobox_2)
hlay.addLayout(vlay)
self.button = QtWidgets.QPushButton(text)
self.button.clicked.connect(self.clicked)
hlay.addWidget(self.button)
self.setFixedSize(self.sizeHint())
class Run_script(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Run_script, self).__init__(parent)
self.setupUi(self)
print("Run script initizalised")
self.PB_create_cb.clicked.connect(self.click_select)
def create_V_0_object(self, attributes):
v_list = []
for x in attributes:
for key, value in x.items():
w = Widget(key, value)
w.clicked.connect(self.buttonClicked)
v_list.append(w)
return v_list
def buttonClicked(self):
w = self.sender()
print(w.combobox_1.currentText())
print(w.combobox_2.currentText())
print(w.label.text())
print(w.button.text())
def click_select(self):
selection = [{"Category1":{"Attr1": "test1","Attr2":"test2"}},{"Category2":{"Attr1": "test3", "Attr2": "test4"}}]
v = self.create_V_0_object(selection)
self.create_horizontal_display(v)
def deleteItemsOfLayout(self,layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
self.deleteItemsOfLayout(item.layout())
def create_horizontal_display(self, vertical_layout_list):
self.deleteItemsOfLayout(self.HLayout_0)
for i, x in enumerate(vertical_layout_list):
self.HLayout_0.addWidget(x)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
prog = Run_script()
prog.show()
sys.exit(app.exec_())
推荐阅读
- mysql - 当表已经在 SQL 中时,将数据帧从 R 发送到 mySQL?
- java - 一维数组的高斯滤波器
- java - 与服务器终端通信的套接字
- c# - 如何在 Xamarin Forsm 中打开图像并将其与 EmguCv/OpenCvSharp 一起使用?
- bash - Linux 重击;操作 PATH 类型 var
- c - 如何在关于字符串的函数中调用函数?
- python - 熊猫数据框重新设计/重新排序问题
- dependencies - 我可以在 Arch Linux 中更新软件包依赖项吗?
- mysql - MySQL 查询到 COPY/INSERT 行以获取一年的数据
- javascript - 将带有 imaskjs 的后缀添加到 html 输入