获取添加到 QMainWindow 的 dock-widget 的引用

Get reference of dock-widget added to QMainWindow

我用的是一个用Qt编写的软件,它有一个QMainWindow object。当添加到 QMainWindow object 已经存在时,我需要获取小部件的引用。我看过 Qt 文档。我希望有活动 childAdded 之类的,但我找不到任何东西。

请查看此代码:

import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QMainWindow, QDockWidget
from PyQt5.QtCore import Qt

class MainWindow(QMainWindow):    
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)    
        self.button = QPushButton("A Button!")
        self.setCentralWidget(self.button)

def do_something(w):
    w.setWindowTitle("Newly Added")

def add_dock_widget(win):
    win.addDockWidget(Qt.RightDockWidgetArea, QDockWidget())

app = QApplication(sys.argv)
window = MainWindow()
window.show()

add_dock_widget(window)
# At this point, somehow, I need to get the reference of added widget.
# Because add_dock_widget method doesn't return any reference.

# I'm looking for something like that, so that I can manipulate the widget:
# window.childAdded[****].connect(do_something)

app.exec_()

该软件允许在其中编写 python 脚本。当 child 添加到 GUI 时,我需要使用脚本更改 child 中的某些内容。

您可以简单地 return 来自 add_dock_widget 的停靠栏小部件,如下所示:

def add_dock_widget(win):
    dock = QDockWidget(win)
    win.addDockWidget(Qt.RightDockWidgetArea, dock)
    return dock

app = QApplication(sys.argv)
window = MainWindow()
window.show()

dock = add_dock_widget(window)

do_something(dock)

根据您的背景目标,有几种选择:

- findChild() 或 findChildren():

如果您知道对象 class,您可以使用 findChild 或 findChildren:

if __name__ == '__main__':

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()

    add_dock_widget(window)
    dockwidget = window.findChild(QDockWidget)
    do_something(dockwidget)

    # or
    # for dockwidget in window.findChildren(QDockWidget)
    # do_something(dockwidget)

    app.exec_()

但是这种方法是有限的,因为你可以有很多相同类型的小部件,你无法区分哪个对象是你想要的,所以你将不得不做一些在另一个功能中传递的新过滤器。

- 覆盖事件方法或使用事件过滤器:

class MainWindow(QMainWindow):    
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)    
        self.button = QPushButton("A Button!")
        self.setCentralWidget(self.button)

    def event(self, e):
        if e.type() == QEvent.ChildAdded:
            if isinstance(e.child(), QDockWidget):
                do_something(e.child())
        return super(MainWindow, self).event(e)
class ChildAddedFilter(QObject):
    def __init__(self, widget):
        super(ChildAddedFilter, self).__init__(widget)
        self._widget = widget
        self._widget.installEventFilter(self)

    def eventFilter(self, o, e):
        if o is self._widget and e.type() == QEvent.ChildAdded:
            if isinstance(e.child(), QDockWidget):
                do_something(e.child())
        return super(ChildAddedFilter, self).eventFilter(o, e)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    window = MainWindow()
    f = ChildAddedFilter(window)
    window.show()
    add_dock_widget(window)
    app.exec_()