QSizeGrip无法调整无边框窗口大小,如何解决?
解决无边框窗口中QSizeGrip无法调整大小的问题
问题根源
- 主窗口调用
setFixedSize(400, 200)固定了窗口尺寸,直接禁用了QSizeGrip的调整功能 - QSizeGrip被底部状态栏遮挡,无法接收鼠标交互事件
- 标题栏最大化按钮的逻辑颠倒,导致窗口状态切换错误
修复步骤
- 移除固定窗口大小限制:删除
setFixedSize,改用resize初始化窗口尺寸,保留可调整性 - 调整QSizeGrip的布局位置:将其添加到状态栏的布局中,确保显示在右下角且不被遮挡
- 修正最大化按钮逻辑:调整状态判断条件,确保最大化/还原操作正确
- 优化窗口拖动逻辑:修复鼠标拖动时的坐标计算错误
修改后的完整代码
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
相关产品推荐
相关产品推荐

