2014-04-04 51 views
2

是否可以將參數傳遞給PyQt4信號連接?在我來說,我有ň按鈕與一組相同的菜單界面上dinamically創建的,這取決於用戶的輸入:將參數傳遞給PyQt信號連接

for j in range(0, len(self.InputList)): 

    arrow = QtGui.QPushButton(Form) 
    arrow.setGeometry(QtCore.QRect(350, 40*(j+3)+15, 19, 23)) 

    menu = QtGui.QMenu(Form) 
    for element in SomeList: 
     cb = QtGui.QRadioButton(element,menu) 
     ca = QtGui.QWidgetAction(menu) 
     ca.setDefaultWidget(cb) 
     QtCore.QObject.connect(cb,QtCore.SIGNAL("stateChanged(int)"),self.SomeFunction) 
    arrow.setMenu(menu) 

雖然菜單是所有的按鈕進入界面相同,用戶應能夠從任何按鈕中選擇一個值,並且對於其中的任何一個,操作都是相同的(「將所選值添加到線條編輯」),唯一的區別在於線條編輯可能也是1st作爲第二,第第3

我想什麼要問的話,就是如果有任何的方式來傳遞參數Ĵ這裏:

QtCore.QObject.connect(cb,QtCore.SIGNAL("stateChanged(int)"),self.SomeFunction(j)) 

在此執行用戶的輸入是3 ,所以我將有3行編輯和三個按鈕與相同的菜單:

Line Edit 1: 
Line Edit 2: 
Line Edit 3: 

使用相同的功能SomeFunction,我想編輯線條編輯的值。因此,如果用戶觸摸連接到2號線編輯菜單,功能SomeFunction應與參數2 SomeFunction(2)被調用,因此同樣的方法瞭解自己這行編輯是正確的:

Line Edit 1: 
Line Edit 2: modified 
Line Edit 3: 

我需要這樣做是因爲主窗口上的行編輯數量取決於用戶選擇的內容。我是一個新手,到目前爲止,我一直爲GUI中的任何對象創建一個函數,但這次數字是動態的,我相信有一些更優雅的方法來創建這種信號連接,我儘管離我的文件閱讀還有些差距。

回答

1

He re是一種不同的方法:不是將數據作爲參數附加到信號處理程序,而是將其附加到菜單項本身。這提供了更大的靈活性,因爲數據不會隱藏在匿名函數中,因此可以被應用程序的任何部分訪問。

這很容易實現,因爲Qt已經提供了必要的API。這裏是你的代碼示例如果你採取這種方法:

 for j in range(0, len(self.InputList)): 

      arrow = QtGui.QPushButton(self) 
      arrow.setGeometry(QtCore.QRect(350, 40*(j+3)+15, 19, 23)) 

      menu = QtGui.QMenu(self) 
      group = QtGui.QActionGroup(menu) 
      for element in SomeList: 
       action = menu.addAction(element) 
       action.setCheckable(True) 
       action.setActionGroup(group) 
       action.setData(j) 
      arrow.setMenu(menu) 

      group.triggered.connect(self.SomeFunction) 

    def SomeFunction(self, action): 
     print(action.data()) 
+0

我認爲我們非常接近解決方案。對不起,我是一個新手,但在實現你的解決方案後,我可以將這個元素傳遞給函數:'print action.data()' - >''。我如何檢索我附加到菜單的字符串值'element',如'action.text()'? –

+0

我這樣問,因爲當調試腳本時,我沒有看到任何字符串文本到對象'action'中。假設我有'SomeList = ['option1','option2','option3']',我需要的是當按鈕的動作'option2'被按下時,相應的行編輯應該獲得值'option2'。所以我想到的是定義'SomeFunction'來將行編輯的'text()'設置爲'option2',並且傳遞參數的原因是要傳遞一個軟件窗戶是正確的。 –

+0

不要緊,這是一個愚蠢的拼寫錯誤('.Text()'而不是'.text()'),我認爲這是一個缺失的屬性。你的解決方案使用'action.text()'非常有效,非常感謝! –

0

我認爲這應該有所幫助。

self.op = "point" 
QtCore.QObject.connect(self.radioButton, QtCore.SIGNAL("clicked(bool)"),lambda : self.anyButton(self.radioButton.isChecked(),self.op)) 

def anyButton(self,kol,vv): 
    print kol 
    print vv 

輸出是

>>> 
True 
point 

你可以看看這個:PyQt sending parameter to slot when connecting to a signal

+0

嗨,謝謝你的回答。不幸的是,我已經嘗試過這種方法,但似乎有問題。正如我在上面寫的,我正在'for'循環中創建'j範圍(0,n)'菜單(儘管它們中的任何一個都有相同的單選按鈕列表)。然而,會發生什麼,輸出總是'n'。所以基本上雖然我通過'QtCore.QObject.connect(cb,QtCore.SIGNAL(「clicked(bool)」),lambda:self.SomeFunction(cb.isChecked(),j))',函數總是用' j == n'。它似乎覆蓋了以前的'j = 0,1,... n-1'值,爲什麼? –

+0

使用'j'的值是調用lambda函數時的'j'的值,而不是定義lambda函數時的'j'的值。看到這個職位的解決方案:http://stackoverflow.com/questions/19510860/qtcore-qobject-connect-in-a-loop-only-affects-the-last-instance –

2

注意,您使用的是PyQt的信號/槽實施的過時版本has been removed in PyQt5(和即使它在PyQt4中的當前實現有點bug)。

如果可能,我會更改代碼中的SIGNAL/SLOT語法。

新的信號/槽機制的工作方式是這樣的:

class Worker(QThread): 
    stateChanged = Signal(int) 

    .... 

    def some_method(self): 
     self.stateChanged.emit(1) 

在GUI線程,你同樣也會有這樣的事情(假設worker = Worker()某處定義:

class GUI(QDialog) 

    worker = Worker() 

    def __init__(self, parent=None): 
     super(GUI, self).__init__(parent) 
     self.worker.stateChanged.connect(self.my_desired_method) 

    def my_desired_method(self, param): 
     print param #prints out '1' 

中當然,這個代碼不會「開箱即用」,但是它是PyQt(和PySide)應該如何處理信號/插槽的一般概念。

+0

謝謝,我聽說它已經是一個已棄用的版本,但不幸的是現在很難更改代碼,因爲我需要將結構稍微更改爲不屬於我的項目。不能標記你的答案,但絕對是我將從下一個項目中使用的有用提示+1;) –