PyQt——2. Qt Designer快速入门

1. 介绍

制作程序UI界面,一般可以通过UI制作工具(例如:Qt Designer)和纯代码编写两种方式。在PyQt中,也可以采用这两种方式,以下主要是介绍使用Qt Designer来制作UI界面。


2. QtDesigner 快速入门

  • QtDesigner是专门用来制作PyQt程序UI界面的工具,其生成的UI界面是一个后缀为.ui的文件。
  • 可以通过命令将.ui文件转换为.py格式的文件,并被其他Python文件引用
  • QtDesigner符合MVC(模型-视图-控制器)设计模式,做到了显示和业务逻辑的分离,其具有以下的优点:
    • 使用简单,通过拖拽和点击就可以完成界面设计,还可以随时预览查看效果图
    • 转换Python文件很方便,QtDesigner保存的设计好的用户界面.ui文件,实际上是XML格式的文本文件。如果想要在PyQt中使用该文件,可以通过pyuic5命令将.ui文件转换为.py文件,然后再进行引用。
    • 启动文件我的电脑上目录位于:D:\anaconda\envs\ppocr\Scripts。这个位置与以前版本有很大变化。
    • 我电脑上的版本:
      • python3.7
      • PyQt5 5.15.1
      • PyQt5-tools 5.15.1.2

2.1 新建主窗口

打开QtDesigner,会自动弹出新建窗口对话框,在模板选项中,最常见的就是Widget(通用窗口)和Main Window(主窗口)。
PS:在PyQt5中,Widget被分离出来,用来代替Dialog,并将Widget放入了QtWidget模块库中。

在这里插入图片描述
模板选择Main Window,就会创建一个主窗口,可以看到主窗口默认添加了菜单栏工具栏状态栏在这里插入图片描述

2.2 QtDesigner界面窗口区域介绍

  • 左边是工具箱(Widget Box),里面的控件支持拖动(拖到主窗口中),包括布局layouts,Buttons按钮等。
    • 在菜单栏中选择“窗体(Form)”→“预览(View/View in)”,或者使用Ctrl+R快捷键。
  • 右边分别是
    • 对象查看器(Object Inspector),可以查看主窗口中放置的对象列表
    • Property Editor(属性编辑器),其中提供了对窗口、控件、布局的属性编辑功能
      • ObjectName 控件对象名称(用于代码编写)
      • geometry 相对坐标系
      • sizePolicy 控件大小策略
      • minimumSize/maximumSize 最小/大宽度 高度
      • font 字体
      • cursor 光标
      • windowTitle 窗口标题(控制显示)
      • iconSize 图标大小
      • toolTip 提示信息
      • statusTip 任务栏提示信息
      • text 控件文本
      • shortcut 快捷键
    • 信号/槽编辑器(Signal/Slot Editor)可以为控件添加/编辑自定义的信号和槽函数
    • 动作编辑器( Action Editor )
    • 资源浏览器( Resource Browser)可以为控件添加图片,比如Label、Button的背景图片

2.3 查看UI文件

如果电脑上不幸安装了UltralSO,那就会看到你的.ui文件默认是这个软件打开的。。将.ui文件拖入文本编辑器,就可以看到xml格式的文本内容了。

直接修改.ui文件中的内容与在界面上进行修改效果是一样的,即使用Qt Designer就能够更快的开发出程序界面,避免了使用纯代码编写带来的繁琐

2.4 .ui文件转为.py文件

方式1
如果使用的是Eirc6 IDE工具,则只需要切换到“窗体”选项卡,选中.ui文件,右击选择“编译窗体”即可。操作完成后,切换回“源代码”选项卡,就可以看到生成的.py文件。然后双击.py文件,点击“开始”菜单→“运行脚本”,或者按F2键,运行结果与.ui呈现结果一致,说明转换成功了。
方式2
使用命令行进行转换

pyuic5 -o XXX.py XXX.ui

pyuic5这个程序默认安装在D:\anaconda\envs\ppocr\Scripts
在这里插入图片描述
注意:在命令行使用的时候要激活特定的conda环境,不然会报错(如果不修改-o的地址,默认就产生在当前命令行目录下)
在这里插入图片描述
转换后类似下图(真是厉害!):
在这里插入图片描述

2.5 界面与逻辑分离

我们将由.ui文件编译来的.py文件称为界面文件

由于界面文件每次编译时都会初始化,所以需要新建一个.py文件调用界面文件,这个新建的.py文件被称为逻辑文件或者业务文件

界面文件和逻辑文件是两个相对独立的文件,这样就实现了界面和逻辑的分离。

实现界面和逻辑分离的方法很简单,新建一个xx.py文件,并继承界面文件的主窗口类即可。

例如:(在上面文件里,窗口类是 Ui_MainWindow,假设上面那个文件是test.py)。

import sys
from PyQt5.QtWidgets import QApplication,QMainWindow

from test import *
class MyWindow(QMainWindow,Ui_MainWindow):
	def __init__(self,parent=None):
		super(MyWindow,self).__init__(parent)
		self.setupUi(self)

if __name__=="__main__":
	app=QApplication(sys.argv)
	myWin=MyWindow()
	myWin.show()
	sys.exit(app.exec_())
# 业务文件中的类继承界面的主窗口类即可

然后运行这个逻辑文件,就可以看到和在.ui文件中一样界面的显示了,Ok

这样更新界面时,只需要修改.ui之后,编译成对应的.py文件即可,逻辑文件视情况进行一些调整,一般不会调整很多。

这样逻辑和界面分离,对于新手就非常友好。


3. 布局管理入门

Qt Designer提供了4种窗口布局方式,分别是:

  • Vertical layout 垂直布局:控件默认按照从上到下的顺序进行纵向添加
  • Horizontal layout 水平布局:控件默认按照从左到右的顺序进行横向添加
  • Grid Layout 栅格布局:将窗口控件放入一个网格之中,然后将它们合理的划分成若干行(row)和列(column),并把其中的每个窗口控件放置在合适的cell单元中,这里的单元就指行和列交叉划分出的控件。
  • Form Layout 表单布局:控件以两列的形式布局在表单中,其中左列包含标签,右列包含输入控件。

这四种布局选项,位于界面左侧的工具箱(Widget Box)的Layouts布局栏中(也是拖动到主窗口中进行使用)。

一般进行布局有两种方式:一是通过布局管理器进行布局;二是通过容器控件进行布局

3.1 使用布局管理器布局

可以尝试新建一个QWidget控件,在其中放入两个子控件:一个文本框lineEdit和一个按钮pushButton,选中控件,右键选中“布局”,就可以指定该空间的布局方式了,如下面所示的水平布局在这里插入图片描述
(选中两个,就表明这两个一起是水平的。)
此外,在对象管理器中也可以看到(QWidget是水平管理布局以及label和button的父控件对象)在这里插入图片描述
此外,如果是从工具箱拖放布局控件的,则其属性所有的margin默认都是0。可以设置这个marigin来控制布局中控件距离这个 框的上下左右边界(布局的内边界的距离)
在这里插入图片描述

布局后,可以发现对象管理器中有很明显的层次关系:主窗口(MainWindow)→布局(Layout)→控件 这样的层次关系。即:窗口一般作为顶层显示,然后将控件按照我们所要求的的布局方式进行排列。

3.2 使用容器进行布局

容器Containers(左侧的Widget box有一栏内容就是Containers)。随便拖一个容器控件(例如Frame)到主窗口,在frame控件里再放几个控件
如下:在这里插入图片描述
在这里插入图片描述
在对象控制器里可以看到:和上面区别很明显,就是Containers容器取代了layouts对象,成为了布局层次结构最底层的控件的 父控件。

但是在实际转换后的代码中,可以看到实际上,QFrame控件和子控件之间还是有一个QHBoxLayout的,所以使用容器进行控件布局的本质还是调用布局管理器进行的。
在这里插入图片描述

3.3 绝对布局

使用每个控件的geometry属性:设置控件相对于主窗口的坐标和自身控件的大小。不过这种方式比较粗糙,而且每次都是手动矫正,比较麻烦,一般不会采用。


3.5 布局管理器进阶

3.5.1 geometry属性与布局管理器

说完了geometry属性之后,还有一个情况要注意,当子控件使用布局管理器之后,可以看到,属性管理器中该子控件的geometry属性已经变成灰色。
表明该子控件的位置与大小现在由布局管理器接管,与geometry属性无关了。在这里插入图片描述

3.5.2 Horizontal/Vertical Spacer/Line

Widget Box中Spacers栏中有Horizontal Spacer以及Vertical Spacer。Display Widgets栏中有Horizontal Line以及Vertical Line。这几个都是用来分割布局的

如果直接拖一个Vertical Spacer到主窗口,保存时会警告

The file contains top level spacers. They will not be saved
Perhaps you forget to create a layout?

所以这个Spacer应该是放在两个布局之间,最后再用一个大的布局保括起来(注意,这个错误可能有点问题,如果确认没有Spacer控件处于最外层,有布局管理器管理,重启一下QtDesigner就好)

放置好之后,是下图的样子
在这里插入图片描述
全选,然后水平布局,就得到
在这里插入图片描述
预览的效果
在这里插入图片描述
如果觉得左边这个布局应该离右边的开始按钮更远,可以选择那个Horizontal Spacer,在属性中修改:在这里插入图片描述
然后这个Spacer控件就会变宽,然后就可以看到开始按钮更远了。

  • Vertical Spacer和Horizontal Spacer
    在这里插入图片描述
    Display Widgets栏中有Horizontal Line以及Vertical Line
    在这里插入图片描述

PyQt有一个基本原则:主窗口中所有窗口控件都有自己的父类,都是从上到下逐级继承的。

3.5.3 窗口尺寸属性控制:minimumSize、maximumSize和sizePolicy

minimumSize、maximumSize属性用来设置控件在布局管理器中的最小尺寸和最大尺寸
在这里插入图片描述
在属性编辑器里,每个属性在点击value这一栏之后,后面都会有一个小回车箭头的按钮,用于还原默认值/设置。

sizePolicy 每个窗口控件都有属于自己的两个尺寸:

  • 一个是sizeHint(尺寸提示):窗口控件的期望尺寸
  • 一个是minimumSize及maximumSize:窗口控件压缩时能够被压缩到的最小或支持放大的最大尺寸。

sizePolicy的作用是:如果窗口控件在布局管理器中的布局不能满足我们的需求,就可以设置该窗口控件的sizePolicy来实现布局的微调;每个窗口控件都有这个属性,但是不同窗口控件的sizePolicy可能不同。

例如:PushButton控件的
在这里插入图片描述
关于Horizontal /Vertical Policy(水平/垂直策略)的选项说明:

  • Fixed:窗口控件具有其sizeHint所提示的尺寸且尺寸不会改变
  • Minimum:窗口控件的sizeHint所提示的尺寸就是它的最小尺寸,不能被压缩的比这个值更小
  • Maximum:窗口控件的sizeHint所提示的尺寸就是它的最大尺寸,不能被放大的比这个值更大
  • Preferred:窗口控件的sizeHint所提示的尺寸就是它的期望尺寸,但是也可以在Minimum和Maximum规定的值之间波动
  • Ignored:无视窗口控件的sizeHint和minisizeHint所提示的尺寸,按照默认来设置。

3.6 其他要注意的

3.6.1 打破布局

选中一个布局,右击,在弹出的菜单项中选择 layout->break layout
如果是上一步操作就是选择布局,那么这个选项作用和撤销差不多,但是如果是操作了别的步骤再想撤销,就要使用这种方式。
在这里插入图片描述

3.6.2 设置tab键顺序

菜单栏->Edit 编辑->Edit Tab Order 设置Tab键次序
在这里插入图片描述
或者直接在工具栏上找到这个tab顺序界面
在这里插入图片描述
默认是最左侧这个,编辑控件界面。
在这里插入图片描述

在这里插入图片描述
默认是按照控件创建顺序来进行的,如果想要修改Tab键顺序,有两种方式

  1. 可以直接点击序号,就会按照点击次序从1开始。
    在这里插入图片描述
  2. 在主窗口(编辑tab次序界面情况下)中空白处右击,选择Tab Order List 制表符顺序列表ya在这里插入图片描述
    就可以上下调节,或者使用reset复位。
    在这里插入图片描述

3.7 测试程序

参考书籍配套代码PyQt5/Chapter03/

4. 信号和槽关联

4.1 简单介绍

  • 信号(signal)和槽(slot)是Qt的核心机制。在创建事件循环之后,通过建立信号和槽的连接就可以实现对象之间的通信。
  • 信号发射时(emit)。连接的槽函数将会自动执行。在PyQt5中,信号和槽通过QObject.signal.connect()函数连接。
  • 所有从QObject类或者其子类(如QWidget)派生的类都能够包含信号和槽。当对象状态改变时,信号就从这个对象发射出去。槽用于接收信号,但是它们是普通的对象成员函数。信号和槽之间是一种多对多的关系(可以多对一,也可以一对多)
  • 在Qt编程中,通过Qt信号槽机制对界面上的窗口控件的操作进行响应处理。(不同的控件能够发射的信号种类和触发的时机也是不同的)

为控件发射的信号指定对应的处理槽函数一般有三种方法:

  1. 在窗口的UI设计中操作添加信号和槽
  2. 代码连接信号和槽
  3. Eir的“生成对话框代码”的功能产生信号和槽

4.2 使用QtDesigner设置信号和槽

4.2.1 信号槽编辑界面(拖动实现)

QtDesigner提供了基本的编辑信号槽的方法。可以通过以下几种方式进行编辑:

  1. 直接进入信号槽编辑界面
    在这里插入图片描述
    然后点击发射者(例如:关闭窗口button),按住左键拖动到接受者(MainForm窗体上),然后就会弹出一个连接配置框。选中左下角的复选框(显示从QWidget中继承的信号和槽),然后closeWinBtn(关闭窗口那个Button的ObjectName重命名后的名称)选择cliked()信号,然后Form的槽函数中选择close(),这表示按下closeWinBtn后,发射cliked()信号,这个信号会被Form窗体的槽函数close捕获,然后出发Form窗体close行为。

类似下图:在这里插入图片描述
选定信号和槽函数后,变蓝色。此时,Ctrl+R预览,点击关闭窗口按钮,已经可以触发槽函数了。
在这里插入图片描述

把界面文件进行转换,编译为.py文件,然后再使用业务文件进行调用,确实也实现了关闭效果。在这里插入图片描述
可以看到 界面文件转换后 是由这几行代码完成信号槽的功能的。

注意:使用QObject.signal.connect()连接的槽函数不要加括号,不然会报错。

业务文件其实很简单,貌似都是统一的格式(继承,然后启动一个主函数,接受系统函数,然后显示,然后窗体程序结束整个程序就结束)

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from ui2test import Ui_MainWindow


class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    myWin.show()
    sys.exit(app.exec_())

4.2.1 信号槽编辑器

在这里插入图片描述
通过下拉框选择发射者发射者的信号接受者接受者的槽处理函数

在这里插入图片描述
在这里插入图片描述
这里的现象是:初始时两个label都呈现,复选按钮选择没有选中;点击一次选择 2(label_8)消失,1(label)仍然出现;再点击,2(label_8)出现,1(label)仍消失。
即(CheckBox每次的bool要么为true 要么为false,每次点击CheckBox,就会发送选中/未选中的信号给两个label,然后二者根据那个信号去使用槽函数做处理)
在这里插入图片描述

5.菜单栏与工具栏

5.1 菜单栏

主窗口在创建时默认就包含菜单栏、工具栏以及任务栏。

双击菜单栏:在这里输入(Type Here)就可以开始输入文字,回车即可生成菜单。
还可以在菜单后面加上类似:文件(&F)英文的括号和符号,来加入快捷键
在这里插入图片描述在这里插入图片描述
一级菜单下还可以一直加入子菜单,(回车表示确认)在这里插入图片描述
子菜单可以通过动作编辑器或者属性编辑中的shorcut来添加快捷键(创建了子菜单后,这个是自动出现的。。。)在这里插入图片描述
双击需要编辑的菜单内容的Name,就可以设置它的图标、快捷键等。(在预览中,点击 打开/关闭/新建 这些功能都无效)
在这里插入图片描述

5.2 工具栏

使用Qt Designer默认生成的主窗口中不显示工具栏,可以通过单击鼠标右键来添加工具栏。(随便找个主窗体中空白的地方右击就好了)在这里插入图片描述

然后在动作编辑器里添加一个新的动作在这里插入图片描述
然后将刚刚创建的这个动作拖入新建的工具栏中(拖动的时候会出现红色的线表示定位)在这里插入图片描述
在这里插入图片描述

5.3 测试上述功能

把界面文件转为.py。实现文件的打开/关闭/新建都是在业务代码里完成的,

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow,QWidget,QFileDialog
from ui2test import Ui_MainWindow


class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)

        # 文件菜单栏下的关闭 关闭窗体
        # actionguanbi 是 关闭 动作 的Name
        self.actionguanbi.triggered.connect(self.close)
        # 文件菜单栏下的打开 执行自定义函数
        self.actiondakai1.triggered.connect(self.openMsg)

    def openMsg(self):
        file,ok=QFileDialog.getOpenFileName(self,"打开","C:/","All Files (*);;Text Files (*.txt)")
        self.statusBar.showMessage(file)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    myWin.show()
    sys.exit(app.exec_())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吨吨不打野

解决了问题,觉得还行就给点

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值