2015-04-01 76 views
1

說我有實現一個小部件,它需要處理的部件C.發送但是小部件的信號沒有插件C的參考(在租賃很麻煩得到)。什麼是正確的方法?手柄信號是未知

下面是一個簡單的例子:

class WidgetA(QtGui.QWidget): 
    def __init__(self): 
     self._tab_widget = QtGui.QTabWidget() 
     self.layout().addWidget(_tab_widget) 
     self._tab_widget.addTab(WidgetB()) 
     self._tab_widget.addTab(...) 

    def show_another_tab(self, index): 
     self._tab_widget.setCurrentIndex(index) 

class WidgetB(QtGui.QWidget): 
    def __init__(self): 
     self.layout().addWidget(WidgetC()) 

class WidgetC(QtGui.QWidget): 
    show_another_tab = QtCore.pyqtSignal() 
    def __init__(self): 
     button = QtGui.QPushButton("show_another_tab") 
     button.clicked.connect(lambda: self.show_another_tab.emit(2)) 

所以基本上,我有一個以上的標籤。其中一個選項卡中有一個小按鈕。當用戶點擊按鈕時,我想切換到另一個選項卡。可惜的是,這個按鈕是WidgetA的一個孩子的孩子,所以我在WidgetA中保留一個按鈕的引用是很麻煩的。可以在運行時動態創建更多按鈕。

什麼是在這種情況下,使用信號的正確方法?或者我應該將WidgetA引用到全局變量中(我真的不想這麼做,但似乎是最簡單的方法)?

+0

從插件℃的信號連接到插件B的信號,而信號連接到一個微件的槽? – thuga 2015-04-01 12:04:32

+0

@thuga我不知道這是否是一個好主意,如果我有另一小d是小部件℃的孩子,小部件want't處理來自d的信號。 – kkpattern 2015-04-02 01:30:56

+0

然後你可以重新設計你的應用程序,這樣你就不會有這樣的問題,或者你可以只從小部件d連接一個信號到小部件c的信號。 – thuga 2015-04-02 06:47:30

回答

0

獲得,如果你是如何設置的父母一致的參考不一定是累贅。如果你這樣做你的榜樣,你可以這樣做:

class WidgetA(QtGui.QWidget): 
    def __init__(self): 
     ... 
     self._tab_widget.addTab(WidgetB(self)) 

    def show_another_tab(self, index): 
     self._tab_widget.setCurrentIndex(index) 

class WidgetB(QtGui.QWidget): 
    def __init__(self, parent): 
     self.layout().addWidget(WidgetC(self)) 

class WidgetC(QtGui.QWidget): 
    show_another_tab = QtCore.pyqtSignal() 
    def __init__(self, parent): 
     ... 
     button.clicked.connect(
      lambda: self.parent().parent().show_another_tab.emit(2)) 

但是,如果你想避免的parent()來電長鏈,更具全球性的做法可能會更好。要做到這一點的方法之一是設置qAppQApplication一個子類:

# do this before QtGui is imported elsewhere 
QtGui.qApp = MyApplication() 

然後,您可以提供訪問的方法,可以讓你瀏覽從自上而下的窗口小部件層次:

 button.clicked.connect(
      lambda: QtGui.qApp.tabManager().setCurrentIndex(2)) 

(注意:明確地設置qApp不是可選的 - 如果不這樣做,您將無法訪問子類的任何屬性)。

+0

我想在其他選項卡甚至其他應用程序中重用WidgetC。所以如果WidgetC不需要知道父母,但只是發出信號會更好。 – kkpattern 2015-04-02 01:40:13

+0

在Qt中沒有類似於通用信號的東西。您始終連接兩個特定對象,即使它們不處於父/子關係。但事實是,在你的例子中,'WidgetC'實例**知道他們的父母,因爲他們引用了'show_another_tab'。他們也知道其他選項卡,因爲它們引用了它們的特定索引。真的,'WidgetA'類應該是負責連接的信號,和'WidgetB'和'WidgetC'類應該具有通用接口(即類似於標準項目模型和它的標準項目)。 – ekhumoro 2015-04-02 02:40:21

+0

對不起,我沒有更清楚地寫出例子。 'WidgetC'沒有引用'show_another_tab','show_another_tab'是它自己的信號。 'WidgetA'碰巧有一個'show_another_tab',我想要在同名的函數中處理'show_another_tab'信號。我注意到qt中除了信號系統外還有一個事件系統。我可以通過eventFilter在'WidgetA'中創建自定義事件並處理此事件嗎?我正在尋找這種方法。謝謝。 – kkpattern 2015-04-02 02:51:26