PyQt5 QDockWidget – 停靠位置改变的信号

  • Post category:Python

QDockWidget 是 PyQt5 中的一个窗口小部件,表示一个可以停靠在主窗口上的小窗口。在使用 QDockWidget 的时候,我们经常需要对其位置进行调整,使用 setAllowedAreas() 方法可以限制停靠的位置,使用 setFloating() 方法可以让它变成一个浮动窗口。而当停靠位置发生改变的时候,我们可以通过 dockLocationChanged 信号来捕获这个事件。

下面我们就来具体讲解如何使用 QDockWidget 的停靠位置改变的信号。

停靠位置改变的信号

在 PyQt5 中,QDockWidget 提供了 dockLocationChanged 信号,用于捕获 QDockWidget 停靠位置改变的事件。该信号可以连接到一个槽函数,以执行相应的操作。信号的定义如下:

QDockWidget.dockLocationChanged(Qt.DockWidgetArea area)

其中,Qt.DockWidgetArea 枚举类型表示停靠区域的四个方向:

  • Qt.LeftDockWidgetArea
  • Qt.RightDockWidgetArea
  • Qt.TopDockWidgetArea
  • Qt.BottomDockWidgetArea

当停靠区域发生变化时,dockLocationChanged 信号会发送一个参数 area,表示新的停靠区域的方向。

示例一:使用信号处理器

下面我们来看一个使用 dockLocationChanged 信号的示例。本例创建一个主窗口和两个停靠窗口,使用信号处理器来捕获停靠位置改变事件,并显示新的位置信息。

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

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.textEdit1 = QTextEdit()
        self.textEdit2 = QTextEdit()
        self.dock1 = QDockWidget("Dock1", self)
        self.dock2 = QDockWidget("Dock2", self)
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Dock Test")
        self.setCentralWidget(QTextEdit())
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock1)
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock2)
        self.dock1.setWidget(self.textEdit1)
        self.dock2.setWidget(self.textEdit2)

        self.dock1.dockLocationChanged.connect(self.onDockLocationChanged)
        self.dock2.dockLocationChanged.connect(self.onDockLocationChanged)

    def onDockLocationChanged(self, area):
        print("Dock location changed to: {}".format(area))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

MainWindow 类中,我们创建了两个 QDockWidget 对象 dock1dock2,并将其添加到主窗口两侧的停靠区域(左侧和右侧)。两个 QDockWidget 分别包含了一个 QTextEdit 对象 textEdit1textEdit2,用于在窗口中显示文本。

接下来,在 initUI() 方法中,我们将 dock1dock2dockLocationChanged 信号连接到一个槽函数 onDockLocationChanged()。在槽函数 onDockLocationChanged() 中,我们使用 print() 方法来输出新的停靠区域。

运行程序,然后拖动 dock1dock2,可以看到停靠位置改变时会输出新的停靠区域信息:

Dock location changed to: 1
Dock location changed to: 2
Dock location changed to: 4
Dock location changed to: 1
Dock location changed to: 0

输出的数字代表不同的停靠区域方向,其中:

  • 0 表示未停靠(浮动)状态
  • 1 表示左侧停靠区域
  • 2 表示右侧停靠区域
  • 4 表示底部停靠区域

示例二:使用lambda表达式

使用信号处理器是一种比较通用的方法,但是如果只是想简单地在位置变化后执行一个函数,可以直接使用 lambda 表达式作为槽函数。

下面我们来看一个使用 lambda 表达式的示例:

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

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.textEdit1 = QTextEdit()
        self.textEdit2 = QTextEdit()
        self.dock1 = QDockWidget("Dock1", self)
        self.dock2 = QDockWidget("Dock2", self)
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Dock Test")
        self.setCentralWidget(QTextEdit())
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock1)
        self.addDockWidget(Qt.RightDockWidgetArea, self.dock2)
        self.dock1.setWidget(self.textEdit1)
        self.dock2.setWidget(self.textEdit2)

        self.dock1.dockLocationChanged.connect(lambda area: print("Dock location changed to:", area))
        self.dock2.dockLocationChanged.connect(lambda area: print("Dock location changed to:", area))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

在这个示例中,我们省略了 onDockLocationChanged() 槽函数,直接在信号连接中使用 lambda 表达式。例如,下面这行代码:

self.dock1.dockLocationChanged.connect(lambda area: print("Dock location changed to:", area))

与下面这行代码等价:

self.dock1.dockLocationChanged.connect(self.onDockLocationChanged)

只不过使用 lambda 表达式来替代 onDockLocationChanged() 方法,使代码更加简洁。