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

QSizeGrip无法调整无边框窗口大小,如何解决?

解决无边框窗口中QSizeGrip无法调整大小的问题

问题根源

  • 主窗口调用setFixedSize(400, 200)固定了窗口尺寸,直接禁用了QSizeGrip的调整功能
  • QSizeGrip被底部状态栏遮挡,无法接收鼠标交互事件
  • 标题栏最大化按钮的逻辑颠倒,导致窗口状态切换错误

修复步骤

  1. 移除固定窗口大小限制:删除setFixedSize,改用resize初始化窗口尺寸,保留可调整性
  2. 调整QSizeGrip的布局位置:将其添加到状态栏的布局中,确保显示在右下角且不被遮挡
  3. 修正最大化按钮逻辑:调整状态判断条件,确保最大化/还原操作正确
  4. 优化窗口拖动逻辑:修复鼠标拖动时的坐标计算错误

修改后的完整代码

import sys
from PyQt5.QtCore import QPoint, Qt
from PyQt5.QtWidgets import QPushButton, QHBoxLayout, QVBoxLayout, \
    QWidget, QLabel, QDialog, QSizeGrip, QMenuBar, QApplication


class TitleBar(QWidget):
    height = 35

    def __init__(self, parent):
        super(TitleBar, self).__init__()
        self.parent = parent
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.menu_bar = QMenuBar()
        self.menu_bar.setStyleSheet("""
            color: #fff;
            background-color: #23272A;
            font-size: 14px;
            padding: 4px; 
        """)
        self.menu_file = self.menu_bar.addMenu('File')
        self.menu_file_quit = self.menu_file.addAction('Exit')
        self.menu_file_quit.triggered.connect(self.parent.close)
        self.menu_help = self.menu_bar.addMenu('Help')

        self.layout.addWidget(self.menu_bar)

        self.title = QLabel("Test")
        self.title.setFixedHeight(self.height)
        self.layout.addWidget(self.title, alignment=Qt.AlignCenter)

        title_style = """
                            QLabel {
                                color: #ffffff; /* Text color (white) */
                                background-color: #23272a; /* Background color (dark grey) */
                                font-size: 18px; /* Font size */
                                font-weight: bold; /* Bold font */
                                padding: 8px; /* Padding around the text */
                                text-align: center; /* Horizontally center the text */
                            }
                        """
        self.title.setStyleSheet(title_style)

        self.closeButton = QPushButton(' ')
        self.closeButton.clicked.connect(self.on_click_close)
        self.closeButton.setStyleSheet("""
            background-color: #DC143C;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "r";
        """.format(self.height / 1.8, self.height / 1.8))

        self.maxButton = QPushButton(' ')
        self.maxButton.clicked.connect(self.on_click_maximize)
        self.maxButton.setStyleSheet("""
            background-color: #32CD32;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "1";
        """.format(self.height / 1.8, self.height / 1.8))

        self.hideButton = QPushButton(' ')
        self.hideButton.clicked.connect(self.on_click_hide)
        self.hideButton.setStyleSheet("""
            background-color: #FFFF00;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "0";
        """.format(self.height / 1.8, self.height / 1.8))

        self.layout.addWidget(self.hideButton)
        self.layout.addWidget(self.maxButton)
        self.layout.addWidget(self.closeButton)
        self.setLayout(self.layout)

        self.start = QPoint(0, 0)
        self.pressing = False
        self.maximized = False

    def resizeEvent(self, QResizeEvent):
        super(TitleBar, self).resizeEvent(QResizeEvent)
        self.title.setFixedWidth(self.parent.width())

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.start = event.globalPos()
            self.pressing = True

    def mouseMoveEvent(self, event):
        if self.pressing and not self.maximized:
            current_pos = event.globalPos()
            delta = current_pos - self.start
            self.parent.move(self.parent.pos() + delta)
            self.start = current_pos

    def mouseReleaseEvent(self, QMouseEvent):
        self.pressing = False

    def on_click_close(self):
        self.parent.close()

    def on_click_maximize(self):
        self.maximized = not self.maximized
        if self.maximized:
            self.parent.setWindowState(Qt.WindowMaximized)
        else:
            self.parent.setWindowState(Qt.WindowNoState)

    def on_click_hide(self):
        self.parent.showMinimized()


class StatusBar(QWidget):
    def __init__(self, parent):
        super(StatusBar, self).__init__()
        self.parent = parent
        self.initUI()
        self.showMessage("***Test***")

    def initUI(self):
        self.label = QLabel("Status bar...")
        self.label.setFixedHeight(24)
        self.label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.label.setStyleSheet("""
            background-color: #23272a;
            font-size: 12px;
            padding-left: 5px;
            color: white;
        """)
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.label)
        
        # 将QSizeGrip添加到状态栏布局
        self.grip = QSizeGrip(self)
        self.layout.addWidget(self.grip, 0, Qt.AlignBottom | Qt.AlignRight)
        
        self.setLayout(self.layout)

    def showMessage(self, text):
        self.label.setText(text)


class MainWindow(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        # 移除固定大小,改用resize初始化窗口尺寸
        self.resize(400, 200)
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
        self.setStyleSheet("background-color: #2c2f33;")
        self.setWindowTitle('Test')

        self.title_bar = TitleBar(self)
        self.status_bar = StatusBar(self)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.title_bar)
        self.layout.addStretch(1)
        self.layout.addWidget(self.status_bar)
        self.layout.setSpacing(0)
        self.setLayout(self.layout)


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

关键修改说明

  • 替换setFixedSize为resize,恢复窗口可调整性
  • 将QSizeGrip嵌入状态栏布局,确保其可见且可交互
  • 修正鼠标拖动时的坐标计算逻辑,解决窗口拖动偏移问题
  • 调整最大化按钮的状态判断,让窗口状态切换正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:25:54