在使用PyQt编写UI界面时,可以通过Qt Designer这个工具像画图一样灵活地编辑UI界面,生成的ui文件可以通过pyuic工具转为py文件或者直接加载到py代码中使用,实现了UI界面和逻辑代码的分离,符合MVC的架构,开发和维护更为灵活和便捷。
安装PyQt5-tools包之后,在Python安装路径\Lib\site-packages\qt5_applications\Qt\bin
下就可以找到designer.exe,直接运行即可使用。
下面介绍一下Qt Designer的使用技巧。
Qt Designer界面简介
启动Qt Designer后,会弹出下图所示的创建窗口。
左上方的几个模板中,有Dialog、Main Window和Widget三种,分别代表PyQt5中的QDialog、QMainWindow和QWidget这三个窗口类,其中QWidget是QMainWindow和QDialog的父类。
Main Window有菜单栏、工具栏和状态栏,常用于制作主窗口;Dialog方便用来展示信息和提供返回值,经常用于制作顶级对话框,而Widget则比较灵活,既可以用于嵌入其他窗体的窗口也可以用于主窗口。
选好模板后点击创建按钮后就可以进入编辑页面。
左侧为可拖拽使用的基础组件,右上方对象查看器显示所有已有的组件以及层级关系,右侧中间属性编辑器可以查看和修改组件的属性,右下方信号/槽编辑器可以编辑各种点击等操作的触发事件,资源浏览器可导入外部资源进行使用。
然后就可以将左侧所需组件拖拽到窗口中进行自由布局了。
布局
如果只是拖拽组件到窗口中,组件的位置是固定的,窗口进行缩放时组件不能自动适应窗口大小。
这时就需要通过布局(Layout)功能控制组件的位置和大小,从左上角的Layouts中,选择拖入合适的布局,再将所需组件拖入该布局内,其中Vertical Layout和Horizontal Layout分别是垂直布局和水平布局,效果如下
Grid Layout是网格布局,Form Layout则是表单布局,不同布局间可以通过工具栏的按钮进行切换。
如果组件之间想要更加紧凑,不随着缩放窗口而出现间隙的话,可以使用spacers进行填充。
Layout布局不属于组件,因此不能在它上面设置样式,可以将布局转成QWidget等组件再进行样式设置。
属性编辑
通过右侧的属性编辑器,可以对组件的属性和样式进行编辑。
其中,ObjectName属性比较重要,后期业务逻辑代码部分需要通过该属性调用对应的组件,尽量在UI设计时就定好便于区分且避免重复的名字。
另外,点击属性编辑器中的+按钮,可以添加自定义的属性,方便业务逻辑代码使用。
也可以在styleSheet属性中,通过类似于Web 的CSS样式表的QSS样式快速定义组件的显示效果。
QSS 背后其实 Qt 的 Paint 事件,通过样式表来简化手动绘制的操作。如果想要实现一些自定义的图形绘制, 需要代码通过 Qt 的 PaintEvent 实现。
QSS样式的可用参考资料如下:
信号槽连接
通过信号/槽编辑器,可以实现组件的事件回调,比如点击按钮的触发,数据变动触发等等。
其他技巧
鼠标中间方便框选
在窗口中有大量控件和布局时,左键框选功能很容易误操作拖拽了某个控件,此时可以通过鼠标中键进行框选。
Ctrl+r快速预览
通过Ctrl+让快捷键可以快速打开一个预览窗口,查看界面的效果。
修改ui文件
在UI界面编辑完成后,保存出的ui文件实质上是一个 xml 文件,定义规范可以参考官方的 XML scheme 文档。
那么就可以通过文本编辑器打开直接对ui文件进行修改,实现一些特殊需求。
纯按钮窗口
在Qt Designer中创建界面时必须有窗口,不能创建单独的一个组件,此时可以先创建一个Widget窗口。
再将ui文件打开,将其中的QWidget替换成QButton,保存后重新用Qt Designer打开,就可以拥有一个按钮的小窗口了。
给 Widget 添加菜单栏
默认情况下,只有 QMainWindow 可以在 Qt Designer 里面配置 QMenuBar 实现菜单栏。
而通过编辑 ui 文件,然后将QMainWindow的ui文件菜单栏部分拼接到QWidget中,就可以实现菜单栏。
ui文件的使用
转换为py文件
这个ui文件可以通过PySide2或者PyQt5的内置命令转成py文件再进行调用,方法如下:
pyuic5 -o test.py test.ui #或者 pyside2-uic test.ui -o test.py
直接加载ui文件
可以直接将 ui 文件在编译到内存当中,这样每次修改 ui 文件就不需要再额外用 exe 工具进行编译了
# PyQt5加载ui文件 from PyQt5 import uic UI_PATH = "test.ui" # 读取 UI 文件的窗口类型和窗口名 form_class , base_class = uic.loadUiType(UI_PATH) # PySide2加载ui文件 from PySide2.QtUiTools import QUiLoader UI_PATH = "test.ui" # 直接返回组件实例 widget = QUiLoader(UI_PATH)
缺点就是没有了 ui 编译好的 python 文件,组件的自动代码提示也就没有了。
通过Qt.py动态加载ui文件
Qt.py是一个第三方库,可以用 Qt5.0 的方式兼容 Qt4.0,也可以以 PySide2 的书写格式兼容 PySide。
通过Qt.QtCompat的loadUi函数,实现ui文件的动态加载,在ui文件修改后无需转换,只需重启业务逻辑代码即可更新界面。
使用方式如下:
import os from Qt import QtWidgets,QtGui,QtCore from Qt.QtCompat import loadUi class TestWidget(QtWidgets.QWidget): def __init__(self): super().__init__() DIR = os.path.dirname(__file__) ui_path = os.path.join(DIR,"test.ui") # NOTE 加载 ui 文件 loadUi(ui_path,self) # NOTE 执行了 loadUi 之后可以通过 ObjectName 获取到 ui 文件里面的定义的组件了 self.Test_BTN.clicked.connect(lambda: sys.stdout.write("click"))
转载自智伤帝的博客,有修改。
愿所有梦见过远方的人,
心有惊雷,
生似静湖。
《不散的宴席》
——蔡崇达
评论
346547 837555Would love to constantly get updated great web weblog ! . 241189
510378 318351This really is a very good topic to talk about. Typically when I uncover stuff like this I stumble it. This article probably wont do well with that crowd. I will probably be confident to submit something else though. 132074
839559 798651I undoubtedly did not realize that. Learnt something new today! Thanks for that. 971329
154243 563679A person essentially lend a hand to make significantly articles I may well state. That will be the quite very first time I frequented your site page and up to now? I amazed with the research you created to create this certain publish incredible. Excellent activity! 444671
34063 405666extremely good post, i surely enjoy this amazing web site, persist with it 750957
797006 169313Having read this I thought it was really informative. I appreciate you taking the time and effort to put this post together. I once once more discover myself spending strategy to a lot time both reading and commenting. But so what, it was still worth it! 924373
110726 234879Yay google is my king helped me to uncover this wonderful web site ! . 657686