22. MDI窗口设计

一、什么是MDI窗口

  MDI 窗口(Multiple-Document Interface),又称多文档界面,它主要用于同时显示多个文档,每个文档显示在各自的窗口中。MDI 窗口中通常包含子菜单和窗口菜单,用于在窗口或文档之间进行切换。

  用 QMainWindow 建立的主界面,通常会同时建立或打开多个相互独立的文档,这些文档共享主界面的菜单、工具栏和停靠控件,多文档中只有一个文档是活跃的文档,菜单和工具栏的操作只针对当前活跃的文档。主界面要实现多文档操作需要用 QMdiArea 控件,通常把 QMdiArea 定义成中心控件。可以在 QMdiArea 控件中添加多个子窗口 QMdiSubWindow,通常每个子窗口都有相同的控件,当然控件也可以不相同。

  我们可以在终端中使用 pip 安装 pyside6 模块。

pip install pyside6

  多文档区 QMdiArea 和子窗口 QMdiSubWindow 的继承关系如下所示:

QMdiArea与QMdiSubWindow的继承关系

  用 QMdiArea 类和 QMdiSubWindow 类创建多文档实例和子窗口实例的方法如下。

QMdiArea(parent:QWidget=None)
QMdiSubWindow(parent:QWidget=None, flags:Qt.WindowFlags=Default(Qt.WindowFlags))

  QMidArea 类常用的方法及其说明如下:

# 实例方法
addSubWindow(widget:QWidget, flags:Qt.WindowFlags=Qt.WindowFlags()) -> QMdiSubWindow                    # 添加子窗口
removeSubWindow(widget:QWidget) -> None                                                                 # 删除子窗口

setViewMode(mode:QMdiArea.ViewMode) -> None                                                             # 设置MDI区域的视图模式
viewMode() -> QMdiArea.ViewMode                                                                         # 获取MDI区域的视图模式

currentSubWindow() -> QMdiSubWindow                                                                     # 获取当前子窗口

scrollContentsBy(dx:int, dy:int) -> None                                                                # 移动子窗口中的控件
setActivationOrder(order:QMdiArea.WindowOrder) -> None                                                  # 设置子窗口的活跃顺序
activationOrder() -> QMdiArea.WindowOrder                                                               # 获取子窗口的活跃顺序
subWindowList(order:QMdiArea.WindowOrder=QMdiArea.WindowOrder.CreationOrder) -> List[QMdiSubWindow]     # 按照指定顺序获取子窗口列表
activeSubWindow() -> QMdiSubWindow                                                                      # 获取活跃的子窗口

setBackground(background:Union[QBrush, QColor, Qt.GlobalColor, QGradient]) -> None                      # 设置背景,默认是灰色
background() -> QBrush                                                                                  # 获取背景色画刷
setOption(option:QMdiArea.Option, on:bool=True) -> None                                                 # 设置子窗口选项
testOption(opton:QMdiArea.Option) -> bool                                                               # 获取子窗口是否设置了选项

setTabPosition(position:QTabWidget.TabPosition) -> None                                                 # 设置Tab标签的位置
tabPosition() -> QTabWidget.TabPosition                                                                 # 获取Tab标签的位置
setTabShape(shape:QTabWidget.TabShape) -> None                                                          # 设置Tab标签的形状
tabShape() -> QTabWidget.TabShape                                                                       # 获取Tab标签的形状
setTabsClosable(closable:bool) -> None                                                                  # 设置Tab标签是否可关闭
tabsClosable() -> bool                                                                                  # 获取Tab标签是否可关闭
setTabsMovable(movable:bool) -> None                                                                    # 设置Tab标签是否可移动
tabsMovable() -> bool                                                                                   # 获取Tab标签是否可移动
setDocumentMode(enabled:bool) -> None                                                                   # 设置Tab标签是否为文档模式
documentMode() -> bool                                                                                  # 获取Tab标签是否为文档模式

# 槽函数
cascadeSubWindows() -> None                                                                             # 层叠显示子窗口
tileSubWindows() -> None                                                                                # 平铺显示子窗口
closeActiveSubWindow() -> None                                                                          # 关闭正在活动状态的子窗口
closeAllSubWindows() -> None                                                                            # 关闭全部子窗口
activatePreviousSubWindow() -> None                                                                     # 激活上一个子窗口
activateNextSubWindow() -> None                                                                         # 激活下一个子窗口
setActiveSubWindow(window:QMdiSubWindow) -> None                                                        # 设置活跃的窗口

  QMidArea 类常用的信号及其说明如下:

subWindowActivated(arg__1:QMdiSubWindow)   # 当子窗口活跃时发射信号

  QMdiSubWindow 类常用的方法及其说明如下:

# 实例方法
setWidget(widget:QWidget) -> None                                       # 设置子窗口的控件
widget() -> QWidget                                                     # 获取子窗口的控件
isShaded() -> bool                                                      # 获取子窗口是否处于只显示标题栏状态
mdiArea() -> QMdiArea                                                   # 返回子窗口所在的多文档区域
setSystemMenu(systemMenu:QMenu) -> None                                 # 设置系统菜单
systemMenu() -> QMenu                                                   # 获取系统菜单
setKeyboardPageStep(step:int) -> None                                   # 设置用键盘的Page键控制子窗口移动或缩放时的步长
keyboardPageStep() -> int                                               # 获取用键盘的Page键控制子窗口移动或缩放时的步长
setKeyboardSingleStep(step:int) -> None                                 # 设置用键盘的方向键控制子窗口移动或缩放时的步长
keyboardSingleStep() -> int                                             # 获取用键盘的方向键控制子窗口移动或缩放时的步长
setOption(option:QMdiSubWindow.SubWindowOption, on:bool=true) -> None   # 设置选项

# 槽函数
showShaded() -> None                                                    # 只显示标题
showSystemMenu() -> None                                                # 在标题栏的系统菜单图标下显示系统菜单

  QMdiSubWindow 类常用的信号及其说明如下:

aboutToActivate()                                                       # 当子窗口活跃时发射信号
windowStateChanged(oldState:Qt.WindowState, newState:Qt.WindowState)    # 窗口状态改变时发射信号
import sys

from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtWidgets import QMdiArea, QMdiSubWindow
from PySide6.QtWidgets import QLabel
from PySide6.QtWidgets import QMenuBar, QMenu
from PySide6.QtGui import QAction

class MyWidget(QMainWindow):
    def __init__(self):
        # 1.调用父类Qwidget类的__init__()方法
        super().__init__()
        # 2.调用setupUi()方法初始化页面
        self.setup_ui()

    def setup_ui(self):
        # 1.设置窗口对象大小
        self.resize(700, 500)

        # 2.创建MDI窗口
        self.mdiArea = QMdiArea(self)
        self.mdiArea.setGeometry(0, 0, 700, 500)

        # 3.创建菜单栏
        self.menuBar = QMenuBar(self)
        self.setMenuBar(self.menuBar)

        # 4.设置菜单
        self.menu = QMenu("子窗体操作", self)
        self.menuBar.addMenu(self.menu)

        # 5.设置菜单项
        self.new_action = QAction("新建", self.menu)
        self.tile_action = QAction("平铺显示", self.menu)
        self.cascade_action = QAction("级联显示", self.menu)
        self.menu.addActions([self.new_action, self.tile_action, self.cascade_action])

        # 6.为菜单关联信号
        self.menuBar.triggered[QAction].connect(self.action)

        # 7.记录子窗口的个数
        self.count = 0

    def action(self, msg):
        if msg.text() == "新建":
            # 创建子窗口对象
            sub = QMdiSubWindow()
            self.count += 1

            # 设置子窗口的标题
            sub.setWindowTitle(f"子窗口{self.count}")

            # 在子窗口中添加一个标签,并设置文本
            label = QLabel(f"这是第{self.count}个子窗口")
            sub.setWidget(label)
            self.mdiArea.addSubWindow(sub)
            sub.show()
        elif msg.text() == "平铺显示":
            self.mdiArea.tileSubWindows()
        elif msg.text() == "级联显示":
            self.mdiArea.cascadeSubWindows()

if __name__ == "__main__":
    # 1.创建一个QApplication类的实例
    app = QApplication(sys.argv)
    # 2.创建一个窗口
    window = MyWidget()
    # 3.展示窗口
    window.show()
    # 4.进入程序的主循环并通过exit()函数确保主循环安全结束
    sys.exit(app.exec())
posted @   星光映梦  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示