Python 如何将动态创建的小部件绑定到PyQt中的信号?
我有一个表格,里面满是通过按下一个按钮创建的组合框。我的问题是如何找出哪个组合框发生了变化?如果它是一个固定的组合框,我将使用以下选项:Python 如何将动态创建的小部件绑定到PyQt中的信号?,python,user-interface,pyqt,Python,User Interface,Pyqt,我有一个表格,里面满是通过按下一个按钮创建的组合框。我的问题是如何找出哪个组合框发生了变化?如果它是一个固定的组合框,我将使用以下选项: QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.dosomething) QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL("currentIndexChang
QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.dosomething)
QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL("currentIndexChanged(int)"), lambda index: self.dosomething(combo_id, index))
我添加了下面的示例代码,以使其更加清晰:
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(332, 122)
Dialog.setMinimumSize(QtCore.QSize(332, 122))
Dialog.setMaximumSize(QtCore.QSize(332, 122))
self.tableWidget = QtGui.QTableWidget(Dialog)
self.tableWidget.setGeometry(QtCore.QRect(10, 10, 256, 101))
self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
self.tableWidget.setColumnCount(2)
item = QtGui.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
self.tableWidget.setRowCount(0)
self.layoutWidget_6 = QtGui.QWidget(Dialog)
self.layoutWidget_6.setGeometry(QtCore.QRect(280, 30, 40, 54))
self.layoutWidget_6.setObjectName(_fromUtf8("layoutWidget_6"))
self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget_6)
self.verticalLayout_2.setMargin(0)
self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
self.pushButton_2 = QtGui.QPushButton(self.layoutWidget_6)
self.pushButton_2.setAutoDefault(False)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.verticalLayout_2.addWidget(self.pushButton_2)
self.pushButton = QtGui.QPushButton(self.layoutWidget_6)
self.pushButton.setAutoDefault(False)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.verticalLayout_2.addWidget(self.pushButton)
QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("clicked()")), self.add)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_2.setText(QtGui.QApplication.translate("Dialog", "+", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "-", None, QtGui.QApplication.UnicodeUTF8))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(QtGui.QApplication.translate("Dialog", "New Column", None, QtGui.QApplication.UnicodeUTF8))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(QtGui.QApplication.translate("Dialog", "New Column", None, QtGui.QApplication.UnicodeUTF8))
def change(self):
'''Depending on the comboBox whose index has changed,
find the row and insert the right options in the comboBox
in the next column'''
#Find the row
ins = self.tableWidget.focusWidget()
selected_row = self.tableWidget.indexAt(ins.pos()).row()
choice = self.tableWidget.cellWidget(0, selected_row).currentText()
#Select the appropriate options
if choice == 'B':
choices_list = ['4', '5', '6']
if choice == 'A':
choices_list = ['1', '2', '3']
#Set ComboBox in the next column
comboBox = QtGui.QComboBox(self.tableWidget)
font = QtGui.QFont()
font.setPointSize(10)
comboBox.setFont(font)
for combo_ind, i in enumerate(choices_list):
comboBox.addItem(_fromUtf8(""))
comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))
def add(self):
index = self.tableWidget.rowCount()
self.tableWidget.insertRow(index)
comboBox = QtGui.QComboBox(self.tableWidget)
font = QtGui.QFont()
font.setPointSize(10)
comboBox.setFont(font)
for combo_ind, i in enumerate(["A", "B"]):
comboBox.addItem(_fromUtf8(""))
comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))
self.tableWidget.setCellWidget(index, 0, comboBox)
comboBox = QtGui.QComboBox(self.tableWidget)
font = QtGui.QFont()
font.setPointSize(10)
comboBox.setFont(font)
#[1,2,3] is for A
#[4,5,6] is for B
for combo_ind, i in enumerate(['1', '2', '3']):
comboBox.addItem(_fromUtf8(""))
comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))
self.tableWidget.setCellWidget(index, 1, comboBox)
app = QApplication(sys.argv)
app.setApplicationName('MyWindow')
window = QDialog()
ui = Ui_Dialog()
ui.setupUi(window)
window.show()
sys.exit(app.exec_())
您可以尝试使用
lambda
,如下所示
在您的情况下,它可能看起来如下所示:
QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.dosomething)
QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL("currentIndexChanged(int)"), lambda index: self.dosomething(combo_id, index))
您相应地更改了self.dosomething
方法,以获取一个额外的参数(例如,某种ID)。这将允许您传递有关事件的一些标识信息,即事件发生在哪个组合框上,并且作为奖励,您可以对所有组件重复使用一种方法,即使添加了新的组件
另请注意:在您的情况下,信号将向插槽传递一个值(int)。您也需要该信息,因此您将其捕获为lambda的一个参数(上面我称之为index
),并将其与信号用于哪个组合框的标识信息(combo\u id
)一起传递给slot方法
如果您的信号没有向插槽发送任何参数,例如单击按钮,则不需要使用lambda参数,如下所示:
QtCore.QObject.connect(self.button, QtCore.SIGNAL("clicked()"), lambda: self.dosomething(button_id))
希望这有帮助。您需要重新实现要动态创建的小部件。基本上也是这个问题的答案。那么,如何获得组合id和索引呢?
索引是用户在组合框中设置的新索引(信号中传递的int),它是为您设置的。当您动态创建组合框时,您必须以某种方式设置组合id。。。你想怎么做就怎么做,我只是举个例子。您可以在创建组合框并将其信号连接到插槽的同时执行此操作,就像上面所做的那样。有意义吗?在您的add
方法中,您创建了一个组合框,但我看不出您曾经将它的任何信号连接到插槽。看起来您就快到了,只需添加我们已经讨论过的QtCore.QObject.connect
,添加一个方法(上面的dosomething
)来处理事件,使用我在下面的答案中展示的lambda技巧,我想您已经掌握了。