《PyQT5软件开发 - 基础篇》第7章 快速UI设计

在前面的章节,我们是通过代码来实现UI界面,但是当UI界面很复杂时,直接通过代码来实现就比较费神了,接下来我们需要通过Qt Designer来快速设计UI,并转换成相应的Python代码,另外,这样还一个好处,Qt Designer的设计符合MVC的架构,从而实现了UI和逻辑分离,也便于后续的开发工作。

Qt Designer中的操作方式十分灵活,其通过拖拽的方式放置控件可以随时查看控件效果。Qt Designer生成的.ui文件(实质上是XML格式的文件)也可以通过pyuic5工具转换成.py文件。

在开始之前,需要安装QT环境,关于QT的安装请参看笔者的博文:

QT开发环境搭建

接下就是进入正题。

7.1 Qt Designer界面简介

打开Qt Designer,界面如下:

左边是控件栏,提供了很多空间类,我们可以直接拖放到widget中看到效果。每个空间都有自己的名称,提供不同的功能,比如常用的按钮、输入框、单选、文本框等等。

右边是对窗口及控件的各种调整、设置、添加资源(列如:图片)、动作。还可以编辑控件的信号和槽函数,也可以添加自定义的信号和槽函数。

7.1.1 Qt Designer基本控件介绍

Widget Box控件工具箱是按照控件作用类别进行划分的。这里作为实现入门级界面实现,主要介绍最常使用的控件及控件对象相关函数。函数方法知道怎么获取控件输入内容以及如何将后台操作结果输出到界面控件显示的主要函数就可以了。

(1)显示控件
Lable:文本标签,显示文本,可以用来标记控件。
Text Browser:显示文本控件。用于后台命令执行结果显示。

(2)输入控件,提供与用户输入交互
Line Edit:单行文本框,输入单行字符串。控件对象常用函数为Text() 返回文本框内容,用于获取输入。setText() 用于设置文本框显示。
Text Edit:多行文本框,输入多行字符串。控件 对象常用函数同Line Edit控件。
Combo Box:下拉框列表。用于输入指定枚举值。

(3)控件按钮,供用户选择与执行
Push Button:命令按钮。常见的确认、取消、关闭等按钮就是这个控件。clicked信号一定要记住。clicked信号就是指鼠标左键按下然后释放时会发送信号,从而触发相应操作。
Radio Button:单选框按钮。
Check Box:多选框按钮。


7.2 Qt Designer设计实践

7.2.1 Qt Designer开发UI

Step1:打开主界面,选择Main Window模板。

Step2:从Widget Box工具箱中拖拽2个label、2个line Edit、1个Push Button以及1个Text Edit。拖完后如下:

Step3:双击各个控件,修改控件名称(对应属性编辑区中的text,可直接双击控件修改)以及对象名称(对应属性编辑区中的objectName)。对象名称一般也需要修改,默认生成的label_1、label_2这种名称无法直接判断到底是对应哪个控件,到时写代码也不好区分每个控件的作用。

最后点击菜单栏窗体- 预览。预览界面实现效果如下:

Step4:保存文件,我这里保存为ui_main.ui。

【ui_main.ui文件】

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>288</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>150</y>
      <width>111</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>登录</string>
    </property>
   </widget>
   <widget class="QLabel" name="labelUser">
    <property name="geometry">
     <rect>
      <x>90</x>
      <y>80</y>
      <width>72</width>
      <height>15</height>
     </rect>
    </property>
    <property name="text">
     <string>用户名:</string>
    </property>
   </widget>
   <widget class="QLabel" name="labelPassword">
    <property name="geometry">
     <rect>
      <x>90</x>
      <y>120</y>
      <width>72</width>
      <height>15</height>
     </rect>
    </property>
    <property name="text">
     <string>密码:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEditUser">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>80</y>
      <width>113</width>
      <height>21</height>
     </rect>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEditPassword">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>110</y>
      <width>113</width>
      <height>21</height>
     </rect>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>300</x>
      <y>80</y>
      <width>311</width>
      <height>101</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

7.2.2将.ui文件转换为.py文件

使用命令行pyuic5 -o xxx.py xxx.ui转换成.py文件。调用格式为pyuic5 -o {输出文件名} {输入designer设计好的.ui后缀界面文件}。执行结果如下:

【ui_main.py文件】

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ui_main.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 288)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(160, 150, 111, 28))
        self.pushButton.setObjectName("pushButton")
        self.labelUser = QtWidgets.QLabel(self.centralwidget)
        self.labelUser.setGeometry(QtCore.QRect(90, 80, 72, 15))
        self.labelUser.setObjectName("labelUser")
        self.labelPassword = QtWidgets.QLabel(self.centralwidget)
        self.labelPassword.setGeometry(QtCore.QRect(90, 120, 72, 15))
        self.labelPassword.setObjectName("labelPassword")
        self.lineEditUser = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEditUser.setGeometry(QtCore.QRect(160, 80, 113, 21))
        self.lineEditUser.setObjectName("lineEditUser")
        self.lineEditPassword = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEditPassword.setGeometry(QtCore.QRect(160, 110, 113, 21))
        self.lineEditPassword.setObjectName("lineEditPassword")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(300, 80, 311, 101))
        self.textEdit.setObjectName("textEdit")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "登录"))
        self.labelUser.setText(_translate("MainWindow", "用户名:"))
        self.labelPassword.setText(_translate("MainWindow", "密码:"))

7.2.3逻辑代码实现

UI开发完了,接下来计就是业务逻辑。这里就简单的是实现一个用户登陆的功能。代码如下:

# -*- coding: utf-8 -*-
"""
@file                main.py
@author              BruceOu
@version             V1.0
@date                2021-08-06
@blog                https://blog.bruceou.cn/
@Official Accounts   嵌入式实验楼
@brief               main
"""
#导入程序运行必须模块
import sys
#PyQt5中使用的基本控件都在PyQt5.QtWidgets模块中
from PyQt5.QtWidgets import QApplication, QMainWindow

from ui_main import Ui_MainWindow#导入designer工具生成的login模块


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

        #添加登录按钮信号和槽
        self.pushButton.clicked.connect(self.login)
        
        #将窗口控件显示在屏幕上
        self.show()
        
    def login(self):
        #利用line Edit控件对象text()函数获取界面输入
        username = self.lineEditUser.text()
        password = self.lineEditPassword.text()
        #利用text Browser控件对象setText()函数设置界面显示
        self.textEdit.setText("登录成功! \n用户名是: "+ username+ ",密码是: "+ password)
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    #初始化
    main = MainForm()
    
    #程序运行,sys.exit方法确保程序完整退出。
    sys.exit(app.exec_())

运行程序:

通过上述操作,我们熟悉了Qt Designer设计界面,到实现业务逻辑的大致工作流程。通过这个工作流程可以简化工作,实现速度的大幅度提升,赶紧去试试吧。


资源获取方法

1.关注公众号[AI实验楼]
2.在公众号回复关键词[PyQt5]获取资料提取码


欢迎访问我的网站

BruceOu的哔哩哔哩
BruceOu的主页
BruceOu的博客
BruceOu的CSDN博客
BruceOu的简书
BruceOu的知乎

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容