You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自定义QMdiSubWindow标题栏:移除最大化最小化按钮并添加自定义按钮

解决QMdiSubWindow标题栏自定义需求

需求说明

移除QMdiSubWindow标题栏的最小化、最大化按钮,添加带自定义图标的按钮,最终标题栏仅保留关闭按钮和该自定义按钮,同时为自定义按钮绑定点击事件。

实现方案

要实现这个需求,需要从两方面修改DetachableSubWindow类:

  • 调整窗口标志,移除不需要的系统按钮
  • 自定义标题栏,添加自定义按钮并绑定事件

步骤1:设置窗口标志

通过setWindowFlags方法,保留子窗口属性和关闭按钮,移除最小化、最大化按钮。注意QMdiSubWindow必须保留SubWindow标志,否则会脱离QMdiArea成为独立窗口。

步骤2:添加自定义按钮到标题栏

QMdiSubWindow的标题栏是名为mdiSubWindowTitleBar的QWidget,可通过findChild获取该控件,然后在其布局中插入自定义按钮,设置图标并绑定点击事件即可。

修改后的完整代码

import sys
from PyQt6.QtWidgets import (
    QApplication,
    QMainWindow,
    QMdiArea,
    QMdiSubWindow,
    QWidget,
    QVBoxLayout,
    QPushButton,
    QToolButton
)
from PyQt6.QtGui import QIcon
from PyQt6.QtCore import Qt


class DetachableSubWindow(QMdiSubWindow):
    def __init__(self, widget):
        super().__init__()
        self.setWidget(widget)
        
        # 设置窗口标志,仅保留关闭按钮和子窗口属性
        self.setWindowFlags(Qt.WindowType.SubWindow | Qt.WindowType.WindowCloseButtonHint)
        
        # 添加自定义标题按钮
        self._add_custom_title_button()

    def _add_custom_title_button(self):
        # 获取QMdiSubWindow的标题栏控件
        title_bar = self.findChild(QWidget, "mdiSubWindowTitleBar")
        if not title_bar:
            return
        
        # 创建自定义工具按钮
        custom_btn = QToolButton(self)
        # 设置自定义图标(示例用系统图标,可替换为本地路径:QIcon("path/to/your/icon.png"))
        custom_btn.setIcon(QIcon.fromTheme("document-open"))
        # 设置按钮样式匹配标题栏风格
        custom_btn.setStyleSheet("border: none; padding: 2px;")
        # 绑定点击事件
        custom_btn.clicked.connect(self._on_custom_btn_clicked)
        
        # 获取标题栏布局,将自定义按钮插入到关闭按钮左侧
        layout = title_bar.layout()
        if layout:
            layout.insertWidget(layout.count() - 1, custom_btn)

    def _on_custom_btn_clicked(self):
        # 自定义按钮点击事件逻辑,可按需修改
        print(f"自定义按钮触发,当前窗口:{self.windowTitle()}")


class Gathered_Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.mdi_area = QMdiArea()
        self.setCentralWidget(self.mdi_area)
        self.win_instance = {}
        for i in range(1, 6):
            widget = QWidget()
            widget_layout = QVBoxLayout(widget)
            widget_layout.addWidget(QPushButton(f"窗口{i}内的按钮"))
            widget.setWindowTitle(f"窗口{i}")
            self.win_instance[i] = widget

        for window_instance in self.win_instance.values():
            self.populate_window(window_instance)

    def populate_window(self, widget):
        sub_window = DetachableSubWindow(widget)
        self.mdi_area.addSubWindow(sub_window)
        sub_window.show()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = Gathered_Window()
    main_window.resize(800, 600)
    main_window.show()
    sys.exit(app.exec())

代码说明

  • setWindowFlags:用SubWindow确保窗口归属QMdiArea,WindowCloseButtonHint仅保留关闭按钮,自动移除最小化、最大化按钮。
  • _add_custom_title_button:定位标题栏后创建QToolButton,设置图标和样式避免视觉突兀,插入到关闭按钮左侧保证布局合理。
  • _on_custom_btn_clicked:自定义按钮的事件处理函数,可根据业务需求替换为具体逻辑。

内容的提问来源于stack exchange,提问作者Shubham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:18:31