处理来自未知引用的窗口小部件的信号

时间:2015-04-01 10:07:55

标签: qt qt4 pyqt4

说我已经实现了一个小部件A,它需要处理小部件C发送的信号。但小部件a没有小部件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(我真的不想这样做,但似乎是最简单的方法)?

1 个答案:

答案 0 :(得分: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()次呼叫,那么更全面的方法可能会更好。一种方法是将qApp设置为QApplication的子类:

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

然后,您可以提供访问者方法,以允许您从上到下导航窗口小部件层次结构:

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

(注意:显式设置qApp不是可选的 - 如果不这样做,您将无法访问子类的任何属性。)