第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI

一、PyQt5介绍

PyQt5是基于图形程序框架Qt5的Python语言实现,由一组Python模块构成。designer软件可以自己设计图形化界面后,生成相应代码,此做法将图形化和代码进行了分离,更有利于实现我们的业务。

QApplication类:用于管理图形用户界面应用程序的控制流和主要设置。它包含主事件循环,对来自窗口系统和其他资源的所有事件进行处理和调度;它也对应用程序的初始化和结束进行处理,并且提供对话管理;还对绝大多数系统范围和应用程序范围的设置进行处理。

QMainWindow类:提供一个有菜单栏、锚接窗口(如工具栏)和状态栏的主应用程序窗口。

QWidget类:所有用户界面对象的基类。QDialog类和QFrame类继承自QWidget类,这两个类有自己的子类系统(Sub-Class System)。

二、环境准备和安装

Windows 10系统
Python 3.8.2
Pycharm 2019.3


pip install PyQt5

pip install PyQt5-tools   #designer软件的库

三、Qt Designer介绍以及相关用法

  1. 打开designer软件
    Win+S呼出Cornata主面板(搜索框),输入designer,并点击运行,弹出以下界面
    第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第1张图片
  2. 建立新的页面
    Main Windows或Dialog界面,Main Windows页面有菜单栏位,其他子页面无菜单控件

左侧的“Widget Box”就是各种可以自由拖动的组件

中间的“MainWindow - untitled”窗体就是画布

右上方的"Object Inspector"可以查看当前ui的结构

右侧中部的"Property Editor"可以设置当前选中组件的属性

右下方的"Resource Browser"可以添加各种素材,比如图片,背景等等,目前可以不管
第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第2张图片

  1. 修改窗口标题
    第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第3张图片
  2. 编辑菜单栏

只有main windows才有
注意到画布的左上方有个“Type Here”,双击它即可开始编辑菜单栏。菜单栏支持创建多级菜单以及分割线(separator)。
第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第4张图片

  1. 修改组件的object名字,用于后端程序调用
    第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第5张图片
  2. 添加静态图片
    具体方法:https://blog.csdn.net/qq_37431083/article/details/87807546
    第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第6张图片
  3. 添加信号与槽

为按钮添加关闭信号,生成py文件后,此信号已经存在
第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第7张图片

  1. 保存和转化
    保存为ui文件,需要用到pyuic5 -o test.py test.ui将ui文件转化为py文件

test.py

生成py文件后,静态图片的位置需要更改self.graphicsView.setStyleSheet("border-image:url(little_pig.jpg);")

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
  1. 调用生成界面

main.py

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow

import test

if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = test.Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第8张图片

  1. 设置触发和参数传递

Qt中有“信号和槽(signal and slot)”这个概念,不过目前无需深究,也无需在Designer中去设置对应按钮的“信号和槽”,直接在“main.py”中“MainWindow.show()”的后面加入下面这样的一行代码

ui.pushButton.clicked.connect(click_success)

对于传参,有两种解决方案,一种是使用lambda,还有一种是使用functool.partial。在接下来的环节中我们会使用partial。

partial(function, arg1, arg2, ......)
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from functools import partial  #传参
import test

def click_success(ui):
    print("啊哈哈哈我终于成功了!")
    txt=ui.lineEdit.text()  #获得input框的值
    ui.label.setText(txt)  #设定label的值

if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = test.Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    ui.pushButton.clicked.connect(partial(click_success, ui))  #设置触发按钮的槽
    sys.exit(app.exec_())

四、PyQt5 控制逻辑语法

第六十六篇PyQt5 Designer用法和制作小软件,结果输出到GUI_第9张图片

  1. 获取文本值:ui.label.text()
txt=ui.lineEdit.text()  #获得input框的值
  1. 设定值:ui.label.setText(“Hello”),在界面显示
ui.label.setText(txt)  #设定label的值
  1. 获取radio布尔值:ui.radio1.isCheck()
res = ui.radio1.isCheck() #被选中结果为True,为bool值
  1. 设置组件是否用于可见
ui.text1.setVisible(True)  #可见
ui.text1.setVisible(False)  #不可见/隐藏

5 .打开文件获得文件路径

#不是self类的话,第一个参数用None

def read_file(ui):
    # 选取文件
    filename, filetype = QFileDialog.getOpenFileName(None, "选取文件", "C:/", "All Files(*);;Text Files(*.csv)")
    print(filename, filetype)
    ui.lineEdit.setText(filename)  #将完整的路径和文件名显示出来
ui.pushButton.clicked.connect(partial(read_file, ui))  #设置触发按钮的槽
  1. 打开文件夹,获取文件夹路径:
def write_folder(ui):
    # 选取文件夹
    foldername = QFileDialog.getExistingDirectory(None, "选取文件夹", "C:/")
    print(foldername)
    ui.lineEdit.setText(foldername)
    
ui.pushButton.clicked.connect(partial(write_folder, ui))  #设置触发按钮的槽
  1. 用类实现调用

定义的主页面为MainWinows继承的类要为QMainWindow,定义的主页面为Dialog继承的类为QWidget

from PyQt5 import QtWidgets
from test import Ui_MainWindow  # 导入ui文件转换后的py文件
from PyQt5.QtWidgets import QFileDialog


class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(mywindow, self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.write_folder)
        # self.pushButton2.clicked.connect(self.read_file)
        # self.pushButton3.clicked.connect(self.process)

    def read_file(self):
        # 选取文件
        filename, filetype = QFileDialog.getOpenFileName(self, "选取文件", "C:/", "All Files(*);;Text Files(*.csv)")
        print(filename, filetype)
        self.lineEdit.setText(filename)

    def write_folder(self):
        # 选取文件夹
        foldername = QFileDialog.getExistingDirectory(self, "选取文件夹", "C:/")
        print(foldername)
        self.lineEdit.setText(foldername)

    # 进行处理
    def process(self):
        try:
            # 获取文件路径
            file_path = self.lineEdit.text()
            # 获取文件夹路径
            folder_path = self.lineEdit_2.text()

        except:
            fail_result = r'转换失败!'
            self.label_3.setText(fail_result)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ui = mywindow()
    ui.show()
    sys.exit(app.exec_())

因为程序运行只有一个线程,当程序出错时,页面会卡死。尽量使用try,except语句防止app卡死

五、结果输出到GUI

每2000ms轮询一次,输出打印结果到GUI

# -*- coding: UTF-8 -*-
""""=================================================
@Project -> File   :Django -> 二叉树之有序列表
@IDE    :PyCharm
@Author :爱跳水的温文尔雅的laughing
@Date   :2020/4/2 21:56
@Desc   :
=================================================="""

import sys
import time
from PyQt5.QtCore import QObject, pyqtSignal, QEventLoop, QTimer
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QTextEdit
from PyQt5.QtGui import QTextCursor

'''
控制台输出定向到Qtextedit中
'''


class Stream(QObject):
    """Redirects console output to text widget."""
    newText = pyqtSignal(str)

    def write(self, text):
        self.newText.emit(str(text))
        loop = QEventLoop()
        QTimer.singleShot(2000, loop.quit)  #2000ms轮询一次,可以设置短一些
        loop.exec_()


class GenMast(QMainWindow):
    """Main application window."""

    def __init__(self):
        super().__init__()

        self.initUI()

        # Custom output stream.
        sys.stdout = Stream(newText=self.onUpdateText)

    def onUpdateText(self, text):
        """Write console output to text widget."""
        cursor = self.process.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.process.setTextCursor(cursor)
        self.process.ensureCursorVisible()

    def closeEvent(self, event):
        """Shuts down application on close."""
        # Return stdout to defaults.
        sys.stdout = sys.__stdout__
        super().closeEvent(event)

    def initUI(self):
        """Creates UI window on launch."""
        # Button for generating the master list.
        btnGenMast = QPushButton('Run', self)
        btnGenMast.move(450, 50)
        btnGenMast.resize(100, 200)
        btnGenMast.clicked.connect(self.genMastClicked)

        # Create the text output widget.
        self.process = QTextEdit(self, readOnly=True)
        self.process.ensureCursorVisible()
        self.process.setLineWrapColumnOrWidth(500)
        self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
        self.process.setFixedWidth(400)
        self.process.setFixedHeight(200)
        self.process.move(30, 50)

        # Set window size and title, then show the window.
        self.setGeometry(300, 300, 600, 300)
        self.setWindowTitle('Generate Master')
        self.show()

    def printhello(self):
        for i in range(100):
            print('hello: %s'%str(i))

    def genMastClicked(self):
        """Runs the main function."""
        print('Running...')
        self.printhello()

        print('Done.')


if __name__ == '__main__':
    # Run the application.
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    gui = GenMast()
    sys.exit(app.exec_())

你可能感兴趣的:(python,python,pyqt)