PyQt5打包为exe后高分辨率屏幕下控件重叠问题求助
PyQt5打包为exe后高分辨率屏幕下控件重叠问题求助
Hey,我仔细看了你的问题和代码,发现几个关键问题导致了打包成exe后高分辨率屏幕下的控件重叠,咱们一步步来解决:
一、最核心的问题:固定尺寸锁死了控件自适应
你的代码里给好多控件和容器加了setFixedSize、setFixedWidth这类固定尺寸的设置,这直接废掉了PyQt布局系统的自适应能力!在低分辨率下固定尺寸看起来没问题,但到了高分辨率屏幕,系统会自动做DPI缩放,这些被固定死大小的控件就会因为缩放比例冲突挤在一起,甚至重叠。
解决办法:
- 删掉所有
setFixedSize、setFixedWidth的代码,让布局系统自动管理控件的大小和位置 - 如果担心控件太小或太大,可以用
setMinimumSize、setMaximumSize来设置控件的尺寸范围,而不是直接固定死
二、代码里的拼写错误导致布局失效
我还发现代码里有几个低级拼写错误,这些错误在PyCharm里可能会有提示,但打包成exe后可能不会报错,直接导致布局无法正常工作:
- 类名
BlankFormWidgetr写错了,应该是BlankFormWidget(你在__init__里调用的父类是BlankFormWidget) - 窗口布局写成了
QVBVoxLayout,正确的是QVBoxLayout Qlabel应该是QLabel(注意是大写的L)calenderPopup拼写错误,正确的是calendarPopup
这些错误会让布局逻辑混乱,控件自然就乱掉了,先把这些修正过来!
三、高DPI设置的正确打开方式
你已经加了高DPI相关的设置,但有个细节需要调整:
- 你设置了
QT_SCALE_FACTOR=1,这个会强制缩放比例为1,直接抵消了系统的自动DPI缩放,建议删掉这个环境变量 - 环境变量和属性设置的顺序是对的(在
QApplication实例化之前),保持这个顺序就好
另外,打包的时候要注意:用UPX压缩可能会破坏Qt的高DPI配置文件,所以打包时加上--noupx参数,避免这个问题:
pyinstaller --windowed --noupx --name YourAppName your_script.py
四、窗口显示逻辑的小优化
你的代码里同时调用了showMaximized()和show(),这可能导致窗口初始化时布局计算异常,建议只保留showMaximized()就好,不用重复调用show()。
修正后的核心代码示例
我帮你修正了关键错误,去掉了固定尺寸,你可以参考这个版本:
from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5 import QtCore import sys import os # 别忘了导入os模块!你的代码里用了os.environ但没导入 class BlankFormWidget(QWidget): # 修正类名拼写 def __init__(self, parent): super(BlankFormWidget, self).__init__(parent) self.init_UI() self.showMaximized() def init_UI(self): campaignList = ['Campaign 1', 'Campaign 2', 'Campaign 3'] self.groupbox = QGroupBox("Get Statistics", self) self.groupbox.setFont(QFont('Arial', 10)) # 补全遗漏的括号 self.groupbox.setAlignment(QtCore.Qt.AlignTop) # 移除固定尺寸,让布局自动调整大小 self.pagelayout = QVBoxLayout(self) self.pagelayout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) self.labelFromDate = QLabel("From Date:", self) self.labelToDate = QLabel("To Date:", self) self.labelCampaign = QLabel("Campaign:", self) self.labelblankoutputwindow = QLabel("", self) # 修正QLabel拼写 self.dateeditFromDate = QDateEdit(calendarPopup=True) # 修正calendar拼写 self.dateeditFromDate.setDisplayFormat("dd-MMM-yyyy") self.dateeditFromDate.setDateTime(QtCore.QDateTime.currentDateTime()) self.dateeditToDate = QDateEdit(calendarPopup=True) self.dateeditToDate.setDisplayFormat("dd-MMM-yyyy") self.dateeditToDate.setDateTime(QtCore.QDateTime.currentDateTime()) self.comboCampaign = QComboBox(self) self.comboCampaign.addItems(campaignList) self.listboxOutput = QListWidget(self) self.listboxOutput.setMinimumSize(250, 220) # 用最小尺寸替代固定尺寸 self.formlayout = QFormLayout(self) self.formlayout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) self.formlayout.addRow(self.labelFromDate, self.dateeditFromDate) self.formlayout.addRow(self.labelToDate, self.dateeditToDate) self.formlayout.addRow(self.labelCampaign, self.comboCampaign) self.formlayout.addRow(self.labelblankoutputwindow, self.listboxOutput) self.buttongetmonthwisestats = QPushButton('Get Monthwise Stats', self) self.buttongetdailyweeklystats = QPushButton('Get Daily / Weekly Stats', self) self.buttongetnewordersstats = QPushButton('Get New Orders Stats', self) self.buttonGenerateReport = QPushButton('Generate Report', self) self.buttonReset = QPushButton('Reset', self) self.buttonClose = QPushButton('Close', self) self.buttonlayout = QHBoxLayout(self) self.buttonlayout.setAlignment(QtCore.Qt.AlignCenter) # 给按钮添加间距,避免挤在一起 self.buttonlayout.addWidget(self.buttongetmonthwisestats) self.buttonlayout.addWidget(self.buttongetdailyweeklystats) self.buttonlayout.addWidget(self.buttongetnewordersstats) self.buttonlayout.addWidget(self.buttonGenerateReport) self.buttonlayout.addWidget(self.buttonReset) self.buttonlayout.addWidget(self.buttonClose) self.pagelayout.addLayout(self.formlayout) self.pagelayout.addLayout(self.buttonlayout) self.groupbox.setLayout(self.pagelayout) self.windowlayout = QVBoxLayout(self) # 修正布局类拼写 self.windowlayout.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) self.windowlayout.addWidget(self.groupbox) class MyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__() self.blank_form_widget = BlankFormWidget(self) self.setCentralWidget(self.blank_form_widget) self.showMaximized() if __name__ == '__main__': # 移除QT_SCALE_FACTOR=1,避免强制固定缩放比例 os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1" os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" App = QApplication(sys.argv) if hasattr(QtCore.Qt, 'AA_EnableHighDpiScaling'): App.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) if hasattr(QtCore.Qt, 'AA_UseHighDpiPixmaps'): App.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True) ex = MyMainWindow() App.exec_()
按照上面的步骤修改后,不管是在PyCharm里运行还是打包成exe,应该都能自适应不同分辨率的屏幕了。
备注:内容来源于stack exchange,提问作者neo
相关产品推荐
相关产品推荐

