PyQt5使用Designer设计UI的两种实现方式

来源:互联网 发布:云 大数据 广州 编辑:程序博客网 时间:2024/05/23 21:11

    在上一篇博客Python界面库-PyQt5初探中留了一个坑,那就是如何利用Qt的Designer设计出的UI文件。本篇博客就来研究这个问题。请注意:这里只是讲如何使用Ui文件,而不会讲如何设计Ui文件,如何需要学习如何设计Ui的话,请移步到Qt5 GUI编程之类的话题去。

一、Qt的方式

    使用过Qt,尤其是在visual studio中使用过Qt的应该知道,在编码的过程中Qt会对一些特殊文件进行处理,具体如下图所示:
这里写图片描述

  • Designer设计出的以后缀ui结尾的文件,这类文件Qt会使用uic工具进行处理,生成包含空间和布局的ui_xxx.h的c++头文件。
  • 资源文件,Qt可以使用图片等资源文件,这样就可以在程序中使用相对路径,并且可以把这些图片资源打包在程序中,而使用户无法见到。资源文件的后缀名是.qrc,经过rcc工具出来后,生成文件qrc_xxx.cpp,c++的实现文件即完成资源的数据化工作。
  • 源码文件处理。Qt处理的源码文件是有要求的,即对应的需要定义Qt宏Q_OBJECT,这个就是元对象系统moc发挥作用的地方,Qt的信号槽机制的处理就是在moc中进行的,因为如果没有加Q_OBJECT,那么就不能进行moc处理,也就无法使用信号槽机制。

        在Python中,我们也可以使用这个流程来完成Qt UI文件的处理。来看实例。

    1.1、使用Designer设计Ui文件

      这里设计了一个简单的登陆窗口,文件名为Login.ui,如图:
    这里写图片描述

    1.2、uic处理ui文件

      在安装的PyQt5中有uic工具,在%PythonRoot%Python36/Scripts/pyuic5.exe。在命令行中输入如下命令
            pyuic5.exe -o ui_Login.py Login.ui处理完成后会在同目录下生成问价ui_Login.py。这个文件和上面说到的c++头文件ui_xxx.h是一致的,只不过是Python的版本而已。

    1.3、编写使用ui_Login.py的Pythone文件Login.py

    文件Login.py如下:

# -*- coding: utf-8 -*-import sysfrom PyQt5.QtWidgets import QDialogfrom ui_Login import Ui_Loginclass Login(QDialog):    """登录窗口"""    def __init__(self, parent = None):        super(Login, self).__init__(parent)        self.ui = Ui_Login()        self.ui.setupUi(self)        self.ui.labelTips.hide()        # 连接槽函数登录按钮        self.ui.pushButtonOK.clicked.connect(self.slotLogin)        # 连接槽函数退出按钮        self.ui.pushButtonCancle.clicked.connect(self.slotCancle)    def slotLogin(self):        if self.ui.lineEditUser.text() != "admin" or self.ui.lineEditPasswd.text() != "123456":            self.ui.labelTips.show()            self.ui.labelTips.setText("用户名或密码错误!")        else:            self.accept()    def slotCancle(self):        self.reject()

文件Login.py完成了界面的逻辑功能的编写,连接了处理登录和退出的槽函数。

1.4、测试例子demo.py,完成调用ui的操作

# -*- coding: utf-8 -*-import sysfrom PyQt5.QtWidgets import QApplicationimport Loginapp = QApplication(sys.argv)login = Login.Login()if login.exec():    print("登录成功")else:    print("登录退出")sys.exit(app.exec())

以上,就是代码的整个部分,运行后出现如下界面这里写图片描述

1.5、总结和uic实用小技巧

    回顾来看,一个ui文件应该是对应一组文件的:
- Login.ui
- ui_Login.py
- Login.py
    对于这个简单的例子程序来说,这样做有点小题大做,杀鸡用牛刀了,但是对于大一点的项目来说,应该还算是比较合理的。值得一提的是,这种方式处理后,我们的代码可以不依赖与Login.ui文件了,即时你把ui文件删除了,代码正常运行。当然,随之而来就是我们修改玩ui文件后,必须再次进行uic的操作,否则你修改的ui无法在程序中响应。
    对于一个一个ui文件的处理我是深恶痛绝的,因此有了下面的一个小技巧,使用批处理的方式进行uic:

@echo off::查找目录下的所有ui文件::当前目录set root=%cd%call:uicFile %root%::子目录for /f %%a in ('dir /ad/b') do (    call:uicFile %root%\%%a\)pause::查找给定目录下的文件:uicFilefor %%a in (%~1*.ui) do (    ::使用pyuic5处理ui文件为py文件,格式按照Qt的默认格式ui_XXX.py    pyuic5.exe -o %~1ui_%%~na.py %%a    echo build: %%a     echo   ==^>^> %~1ui_%%~na.py     echo.)goto:eof

    这个批处理,完成了查找当前目录和其子目录下的所有ui文件,并自己处理成ui_xxx.py的方式。顿时感觉轻松了不少。

二、Python的方式

    看完上面的例子,是不是感觉qt的ui文件使用还是比较复杂的,是的,本人也有同感,虽然之前一直都是这么用的,但是那是visual studio自己帮我完成了,我根本不需要去理会这些细节的东西。那么问题来了,PyQt5可能帮我处理这些事情吗?于是我抱着问题,去查看了PyQt5.8.2的源码,有了意外的发现,还真的有!!!
    经查找,pyqt5中有一个模块叫做PyQt5.uic,里面有一个方法叫做loadUi就是专门做这个的。以下,还是使用上面的小例子作为描述。

2.1 使用Designer设计Ui文件

这里还是使用1.1中的UI文件

2.2 使用UI文件

    这一步就是1.2中使用uic方式不一样了,我们将不主动进行uic处理,而是选择pyqt5替我们进行。代码如下

# -*- coding: utf-8 -*-import sysfrom PyQt5.QtWidgets import QDialog#重点和秘诀就在这里,大家注意看from PyQt5.uic import loadUiclass Login(QDialog):    """登录窗口"""    def __init__(self, *args):        super(Login, self).__init__(*args)        loadUi('Login.ui', self)   #看到没,瞪大眼睛看        self.labelTips.hide()        self.pushButtonOK.clicked.connect(self.slotLogin)        self.pushButtonCancle.clicked.connect(self.slotCancle)    def slotLogin(self):        if self.lineEditUser.text() != "admin" or self.lineEditPasswd.text() != "123456":            self.labelTips.show()            self.labelTips.setText("用户名或密码错误!")        else:            self.accept()    def slotCancle(self):        self.reject()

2.3 测试例子demo.py

    测试例子和1.4中的demo.py完全一模一样,所以不再列出。运行效果也是一样的,我又截了一张图,省的大家伙觉得是上面的结果:
这里写图片描述

2.4 总结

    使用PyQt5自动帮我们解决ui到Python的问题,这样使得我们在ui上修改完成后,不需要做任何处理就可以表现在代码程序中,这样也直接的少了一个ui_xxx.py文件,好处不少啊!但是有什么不好的地方,还是说在运行时才处理ui文件会不会造成性能的问题,我暂时还没有什么想法,反正这简单的demo程序是没有任何问题的。各位大神如果有想法欢迎指教。

    好了,以上就是这篇长博客的全部内容了, 欢迎参观,欢迎讨论指正不足之处。