说我已经实现了一个小部件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(我真的不想这样做,但似乎是最简单的方法)?
答案 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
不是可选的 - 如果不这样做,您将无法访问子类的任何属性。)