【Qt】运行py加载ui文件,顶层窗口的背景、布局等样式失效(与预览不同),或特定对象和布局无法显示(包括代码生成)

目录

一、问题&情况

二、一些解决方法

0、分辨率、屏幕适配问题

1、运行环境问题

三、通用解决方法

更新 (方法更高效耶)


一、问题&情况

遇到的问题:

1. 运行py文件,代码中通过加载ui文件,设置为顶层窗口,运行结果与预览不同,窗口样式失效

2. 或特定对象布局无法显示(包括加载ui方式和代码直接生成方式)

(其中加载ui的代码就是Qt自动生成的加载代码,而样式包括了背景颜色,布局等)

可能的情况:

0、分辨率、屏幕适配问题:

        这个问题不是本文章的主要内容,网上也有很多文章讲关于这个问题的解决办法。其实就是因为运行时默认为非高清屏适配模式,所以显示的格式和大小会有较大出入

1、系统问题:

        我在windows下运行总是出问题,在虚机中Ubuntu内运行就正常显示

2、编译环境问题:

        同在windows下,对于Qt自动生成的加载ui的代码,C++的运行结果就是正常的,而python加载的样式失效

其实1、2都可以归结为运行环境问题,可能是系统、编译器、Qt版本等等导致

3、MainWindows、格珊布局  等

        通过其他一些文章了解到的情况及解释,

        由于MainWindow的特殊格式,或格栅布局等与某些对象不兼容匹配,导致在布局时会出现一些问题(即使加载ui,直接通过代码生成页面)

二、一些解决方法

0、分辨率、屏幕适配问题

python

from PyQt5 import QtCore
'''
或者
from PySide2 import QtCore
'''

QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
'''
app = QApplication([]) # 添加在该句之前即可
......

'''

C++

#include "mainwindow.h"

#include 

int main(int argc, char *argv[])
{
    if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

1、运行环境问题

根据博客

QT 顶级窗口为QWidget 设置顶级窗口背景无效_漫步繁华街的博客-CSDN博客_qwidget 顶级窗口

该文章中表达意思,对于顶层窗口,默认不加载ui文件的样式(显然通过我上面提到的C++和Ubuntu测试,该结论是不太对的)

解决方法就是,可以通过一系列的添加设置为,指定的窗口样式

但文章中只提到了,如何设置背景颜色,且是对于C++的

如果将顶层全部手动设置,使用ui是否就有些鸡肋了,花那么多时间找解决办法,还不如直接全部手敲代码来的快一些

三、通用解决方法

该方法受启发于博客(谢谢!!!比心心!

pyqt使用全局格珊布局无法正常显示问题解决_Puppet-Master的博客-CSDN博客

无论对于1、2还是3,哪种情况,都可以试试下面这种方法

import os
from pathlib import Path
import sys

from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtUiTools import QUiLoader

class Load_widget(QWidget):
    def __init__(self):
        super(Load_widget, self).__init__()
        self.load_ui(self)
        self.retranslateUi(self)

    def load_ui(self, obj):
        obj.setObjectName("obj")     ''' 生成对象->顶层 '''
        obj.resize(600, 420)         ''' 设置大小 '''
        self.horLayout = QHBoxLayout(obj)    ''' 设置布局,布局样式随意均可 '''
        self.horLayout.setObjectName("mainWin_HLayout")   ''' 设置布局名称 '''

        '''
              这一步比较重要,消除顶层窗口布局的边缘大小
              当然可以根据自身需求,保留或其他修改   
        '''
        self.horLayout.setContentsMargins(0, 0, 0, 0)

        loader = QUiLoader()
        path = os.fspath(Path(__file__).resolve().parent / "main_window.ui")  ''' "main_window.ui" 为ui文件名 '''
        ui_file = QFile(path)
        ui_file.open(QFile.ReadOnly)
        ui_tmp = loader.load(ui_file)
        self.horLayout.addWidget(ui_tmp)  ''' 将ui窗口放入生成的顶层窗口的布局中 '''
        ui_file.close()

    def retranslateUi(self, obj):
        _translate = QCoreApplication.translate
        obj.setWindowTitle(_translate("obj", "My MainWindow"))  ''' 设置窗口名称 '''

if __name__ == "__main__":
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)  ''' 分辨率自动适配高清屏 '''
    app = QApplication([])
    main_widget = Load_widget()
    main_widget.show()
    sys.exit(app.exec_())

(由于颜色原因,为了让注释容易阅读,注释的代码风格有些奇怪,望见谅!)

核心思想就是

把ui文件加载到新的顶层窗口对象当中,这样就变为内部小窗口了

并且可以把边缘距离消除,这样即使是MainWindow,运行显示的结果和预览也没有任何差别

这样,无论是由于环境问题导致加载ui出问题,还是顶层格式不匹配问题,都可以因此解决!

PS. 

顶层窗口大小最好设置得比ui中的否则在某些环境下运行,依然会导致加载后样式失效

最后,

希望这篇blog能够给需要的人带来一些帮助,文章中如果有什么不对的地方,还望各位批评指正。

加油!!!




更新 (方法更高效耶)

经大佬指点,有一个更好用的方法,不要使用Qt自动生成的代码!!!不好使!!!

from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import sys

class Stats:
    def __init__(self):
        qfile = QFile("form.ui")
        qfile.open(QFile.ReadOnly)
        qfile.close()
        self.widget = QUiLoader().load(qfile)


if __name__ == "__main__":
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QApplication([])
    widget = Stats()
    widget.widget.show()
    sys.exit(app.exec_())

这个就不用嵌套窗口啦!!!其实好像就是把继承对象去掉就可以,我是这么理解的。

超好用!

你可能感兴趣的:(qt,ui)