2012-02-08 23 views
3

我的PyQt4/Python3 GUI中有幾個QComboBoxes,它們在初始化過程中充滿了數據庫中的一些條目。初始CurrentIndex設置爲0.還有一個複選框,用於更改組合框中項目的語言。爲了保留當前的用戶選擇,我使用翻譯的項目填寫ComboBox後,將當前項目的索引和setCurrentIndex備份到此編號。所有這些動作都會發出currentIndexChanged信號。從編程化變化中分離用戶交互:PyQt,QComboBox

根據QComboBoxes中選定的項目顯示一些情節。這個想法是在用戶改變任何ComboBox當前項目後立即在線重繪圖形。在這裏我遇到了一個問題,因爲如果每次觸發currentIndexChanged信號時重繪圖,我都會在初始化過程中多次重畫它,如果轉換複選框選擇已更改。

什麼是分開這些案件的最佳方式?原則上,我需要從用戶中分離程序化的當前索引更改,並僅在後面的情況下更新繪圖(在GUI初始化期間,我可以編程調用更新繪圖功能一次)。我應該寫/重寫任何信號?如果是這樣,我從來沒有這樣做,並會歡迎任何暗示或一個很好的例子。使用另一個信號?或者也許有辦法暫時阻止所有信號?

回答

9

有幾件不同的事情可以嘗試。首先,你可以確保你在之前完成了所有的初始化工作,你可以在之前連接信號。

其次,您可以使用activated信號,該信號只有在用戶選擇一個項目時纔會發送。 (但請注意,與currentIndexChanged不同,即使索引未改變,也會發送此信號)。

第三,您可以使用blockSignals臨時停止在編程方式更改當前索引時發送的任何信號。

以下腳本演示這些可能性:

from PyQt4 import QtGui, QtCore 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     layout = QtGui.QVBoxLayout(self) 
     self.combo = QtGui.QComboBox() 
     self.combo.setEditable(True) 
     self.combo.addItems('One Two Three Four Five'.split()) 
     self.buttonOne = QtGui.QPushButton('Change (Default)', self) 
     self.buttonOne.clicked.connect(self.handleButtonOne) 
     self.buttonTwo = QtGui.QPushButton('Change (Blocked)', self) 
     self.buttonTwo.clicked.connect(self.handleButtonTwo) 
     layout.addWidget(self.combo) 
     layout.addWidget(self.buttonOne) 
     layout.addWidget(self.buttonTwo) 
     self.changeIndex() 
     self.combo.activated['QString'].connect(self.handleActivated) 
     self.combo.currentIndexChanged['QString'].connect(self.handleChanged) 
     self.changeIndex() 

    def handleButtonOne(self): 
     self.changeIndex() 

    def handleButtonTwo(self): 
     self.combo.blockSignals(True) 
     self.changeIndex() 
     self.combo.blockSignals(False) 

    def changeIndex(self): 
     index = self.combo.currentIndex() 
     if index < self.combo.count() - 1: 
      self.combo.setCurrentIndex(index + 1) 
     else: 
      self.combo.setCurrentIndex(0) 

    def handleActivated(self, text): 
     print('handleActivated: %s' % text) 

    def handleChanged(self, text): 
     print('handleChanged: %s' % text) 

if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

感謝很多很好的例證!我採取了blockSignals解決方案。順便說一句,如果我使用QT設計器而不是程序佈局,那麼實際上是否可以「確保在連接信號之前完成所有初始化」?信號在哪一點被激活? – Katya 2012-02-13 14:14:17

+0

@Katya。使用Qt Designer,您只能將預先存在的信號連接到預先存在的插槽(而不是您自己的處理程序)。因此,在實踐中,幾乎所有的信號都需要在gui建立之後連接(除非應用程序非常簡單)。就我個人而言,我只使用Qt Designer來設計gui,而且很少使用它來連接信號。 – ekhumoro 2012-02-13 19:20:21