python Qt designer 图形界面编程实战

1、概述

      最近做一个模块的开发,刚开始参数是在主函数修改,后来项目需要有一个用户交互界面,方便调试,于是在网上学习了python Qt图形界面的开发(Python Qt 图形界面编程,很实用也很详细的视频课程),顺利完成项目需求,为此写一篇使用教程,供大家参考。
      先看一个自己以租车比价做的例子。有一款名为IGO的租车平台,它有分时用车、2小时套餐、4小时套餐、日租套餐等,每个都有包含的公里数和小时数(分时用车除外),有时候自己租车会计算比价,就想着自己做一个软件出来方便选择套餐,其中的参数均可以手动修改,部分参数有默认值即平台设置的值。界面及操作演示如下:
在这里插入图片描述

      本文主要演示如何使用自己设计的图像界面,例如如何使用多线程打印输出以及不使用多线程会有什么问题,还有就是如何将自己的代码和用户交互、如何弹出提示信息,如何发布自己的程序。

2、相关库安装

pip install pyside2

如果安装过程较慢,可以参考:通过国内镜像下载python库
安装好以后后,在所在python的库安装目录中就有Qt designer的启动程序。
在这里插入图片描述
      新建一个widget:可以设计自己的界面,具体模块可以参考上述视频教程,这里给出即将要演示的已经做好的demo界面,主要是有一个输出文本框(lineEdit)、展示文本框(textBrowser)、两个命令按钮(pushButton),界面如下:
在这里插入图片描述
      将设计模块保存后(.ui文件,本文保存为:demo.ui,demo ui链接, 提取码:5188 )即可利用PySide2中的相关模块进行动态加载。

3、示例代码

from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QWidget, QApplication, QMessageBox
from PySide2.QtCore import Signal, QObject
from threading import Thread
import time

class MySignals(QObject):
    # 定义一种信号,参数为字符串
    text_print = Signal(str)

class Stats(QWidget):

    def __init__(self):
        super().__init__()
        self.ui = QUiLoader().load('demo.ui')
        # 实例化
        self.ms = MySignals()
        # 自定义信号的处理函数
        self.ms.text_print.connect(self.printToGui)
        self.ui.pushButton.clicked.connect(self.print_info_multithread)
        self.ui.pushButton_2.clicked.connect(self.output_msg)

    def printToGui(self, text):
        """
        向文本展示框中添加输出信息
        """
        self.ui.textBrowser.append(str(text))

    def output_msg(self):
        """
        演示弹出对话框信息
        """
        QMessageBox.information(self, "提示", "参数已保存!")

    def print_info_multithread(self):
        """
        演示利用多线程打印输出信息
        """
        def run():
            # 通过Signal 的 emit 触发执行 主线程里面的处理函数
            # emit参数和定义Signal的数量、类型必须一致
            input = int(self.ui.lineEdit.text())  # 演示用户交互接口
            for i in range(input):
                self.ms.text_print.emit('输出内容_{}'.format(i))
                time.sleep(1)
        thread = Thread(target=run)
        thread.start()

    def print_info_no_multithread(self):
        """
        演示不使用多线程打印输出信息
        """
        for i in range(5):
            self.ui.textBrowser.append('输出内容_{}'.format(i))
            time.sleep(1)

app = QApplication()
stats = Stats()
stats.ui.show()
app.exec_()

4、演示结果

(1)多线程的打印输出演示:
在这里插入图片描述
(2)不使用多线程输出演示:
即在class Stats的初始化中:

self.ui.pushButton.clicked.connect(self.print_info_multithread)

更改为:

self.ui.pushButton.clicked.connect(self.print_info_no_multithread)

在这里插入图片描述
      上述两者的区别是,当点击输出时,利用多线程打印展示框时同步输出的,而不使用双线程打印,文本展示框的是阻塞的。
      自己设计界面肯定是用多线程的方法,这里主要展示有可能遇到的错误(自己刚开始也没搞通这个,因为看视频理解错误了)。

5、程序发布

      当我们的界面和程序代码完成后,就可以完成发布了,生成.exe供别人使用。手续需要安装程序打包的python库——pyinstaller:

pip install pyinstaller

      安装完成后进入到,自己程序所在目录,例如运行的python文件为Qt_designer_demo.py:

pyinstaller Qt_designer_demo.py --noconsole --hidden-import PySide2.QtXml

      最后在所在文件目录中的dist文件夹下,会得到一个包含Qt_designer_demo.exe的Qt_designer_demo文件,记得要把demo.ui放到Qt_designer_demo文件夹中,否则加载不了.ui文件,双击exe程序可以看到跟直接运行代码效果一致。
在这里插入图片描述

至此,一个基本的Qt 图像交互界面就完成了,过程也不是很麻烦,自己可以通过Qt designer设计适合自己的界面。

6、.ui转化成python文件

      可能有时候我们不想用动态加载.ui的方法,因为我们每次发布程序后都需要把.ui文件手动移到pyinstaller 生成的文件夹下。这是我们可以利用pyuic5命令将我们生成的.ui文件转化成python文件,然后再调用即可,转化命令为:

pyuic5 -o demo_ui.py demo.ui

      这是我们得到一个demo_ui.py文件,里面是一个包含设计界面的class:

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'multithread_print.ui'
# Created by: PyQt5 UI code generator 5.15.0
# 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_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(445, 307)
        self.verticalLayout = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        '''此处代码较长,省略部分代码'''

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Qt演示"))
        self.label.setText(_translate("Form", "请输入你的数字:"))
        self.pushButton.setText(_translate("Form", "输出"))
        self.pushButton_2.setText(_translate("Form", "保存"))

      为了保持与之前的使用PySide2模块的代码基本一致(PyQt5与PySide2的模块架构基本类似),我们把demo_ui.py中的:

from PyQt5 import QtCore, QtGui, QtWidgets

更改为:

from PySide2 import QtCore, QtGui, QtWidgets

      我们再对原来的运行程序进行修改即可,我们这里我们做了以下更改:
(1)增加模块导入:from demo_ui import Ui_Form
(2)class Stats(QWidget)更改为:class Stats(QWidget, Ui_Form)
(3)初始化中增加:self.setupUi(self)
(4)将相关的self.ui.xxx中的.ui去掉,例如:self.ui.textBrowser.append(str(text))更改为:self.textBrowser.append(str(text))

      具体修改后的代码如下,运行后与动态加载.ui文件方法一致

from PySide2.QtCore import Signal, QObject
from PySide2.QtWidgets import QWidget, QApplication, QMessageBox
from threading import Thread
from demo_ui import Ui_Form
import time

class MySignals(QObject):
    # 定义一种信号,参数为字符串
    text_print = Signal(str)

class Stats(QWidget, Ui_Form):
    def __init__(self):
        super(Stats,self).__init__()
        self.setupUi(self)
        self.ms = MySignals()
        # # 自定义信号的处理函数
        self.ms.text_print.connect(self.printToGui)
        self.pushButton.clicked.connect(self.print_info_multithread)
        self.pushButton_2.clicked.connect(self.output_msg)
    def printToGui(self, text):
        """
        向文本展示框中添加输出信息
        """
        self.textBrowser.append(str(text))

    def output_msg(self):
        """
        演示弹出对话框信息
        """
        QMessageBox.information(self, "提示", "参数已保存!")

    def print_info_multithread(self):
        """
        演示利用多线程打印输出信息
        """
        def run():
            # 通过Signal 的 emit 触发执行 主线程里面的处理函数
            # emit参数和定义Signal的数量、类型必须一致
            input = int(self.lineEdit.text())  # 演示用户交互接口
            for i in range(input):
                self.ms.text_print.emit('输出内容_{}'.format(i))
                time.sleep(1)
        thread = Thread(target=run)
        thread.start()
        
app = QApplication()
stats = Stats()
stats.show()
app.exec_()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南洲.

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值