2013-07-15 2 views
0

У меня есть таблица, полная comboBoxes, созданная нажатием кнопки. Мой вопрос: как узнать, какая comboBox изменилась? Если бы это был фиксированный COMBOBOX, я хотел бы использовать следующее:Как связать динамически созданный виджет с сигналом в PyQt?

QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.dosomething) 

Я добавил пример кода ниже, чтобы сделать его более ясным:

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_()) 
+0

В вашем методе 'add' вы создаете поле со списком, но я не вижу, чтобы вы когда-либо подключали какие-либо его сигналы к слоту. Похоже, что вы почти там, просто добавьте 'QtCore.QObject.connect', который мы уже обсуждали, добавьте метод (' dosomething' вверху) для обработки событий, используйте трюк лямбда, который я покажу в своем ответе ниже, и я думаю, что у вас это есть. – DMH

ответ

1

Одна вещь, вы можете попробовать использует lambda, как в этом similar question.

В вашем случае это может выглядеть следующим образом:

QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL("currentIndexChanged(int)"), lambda index: self.dosomething(combo_id, index)) 

И соответственно изменить метод self.dosomething взять дополнительный параметр (например, идентификатор некоторого вида). Это позволит вам передать некоторую идентифицирующую информацию о событии, т. Е. В каком поле со списком оно произошло, и в качестве бонуса вы можете повторно использовать один метод для всех своих компонентов, даже если новые будут добавлены.

Также обратите внимание: в вашем случае сигнал передает значение (int) в слот. Вам также нужна эта информация, поэтому вы фиксируете ее как аргумент для лямбда (выше, я назову ее index) и передаем ее методу вашего слота вместе с идентификационной информацией (combo_id) о том, для какого комбинированного поля используется сигнал.

Если сигнал не посылает никаких параметров в слот, например, для нажатия кнопки, вам не нужно использовать лямбду-аргумент, например, так:

QtCore.QObject.connect(self.button, QtCore.SIGNAL("clicked()"), lambda: self.dosomething(button_id)) 

Надеется, что это помогает.

+0

Итак, как вы получаете combo_id и индекс? – GiannisIordanou

+0

«index» - это новый индекс, заданный пользователем в вашем поле со списком (передаваемый в сигнале int), который настроен для вас. Combo_id - это то, что вам нужно как-то настроить, когда вы динамически создаете свой поле со списком ... Вы можете сделать это любым способом, как хотите, я просто использовал это в качестве примера. Вы можете сделать это одновременно с созданием поля со списком и подключением его сигналов к слоту, как вы это делали выше. Имеют смысл? – DMH

0

Вам необходимо повторно внедрить виджет, который вы хотите создать динамически. В принципе this code ответ на этот вопрос тоже.

Смежные вопросы