PyQt5:适用于新手的入门级保姆教程

目录

1、简介

2、安装步骤

2.1 安装PyQt5

2.2 Pycharm配置

3、界面设计介绍

3.1 组件

3.1.1 菜单类组件

3.1.2 图标和快捷键设置

3.1.3 分页组件Tab Widget

3.2 整体框架

3.2.1 ui 解析py文件

3.2.2 主函数

3.3 信号和槽

3.2.1 自定义信号和槽

3.4 交互实现



1、简介

PyQt基于QT库的python封装,是一个图形用户界面(GUI)工具包,允许用户使用python语言创建桌面应用程序。目前,不同版本中,PyQt5是较为流行的版本,支持python 2.7 和 python 3.x 。

PyQt支持两种开发方式,可视化和编程化。

 - 编程式创建界面无需多说,pip安装成功以后,有较深基础功底的可直接上手编码。
 - 可视化方式对新手非常友好,用户可基于Qt Designe工具包进行组件拖拽、布局管理等操作。

2、安装步骤

2.1 安装PyQt5

在自己的python虚拟环境中,pip安装依赖包PyQt5, pyqt5_tools
pyqt5_tools 包含一些辅助 PyQt5 的开发工具,其中就有我们要用的 Qt Designer

pip install PyQt5 PyQt5-tools

一般会报错或爆红,建议带上国内镜像源

-i https://pypi.tuna.tsinghua.edu.cn/simple

安装成功以后,win+s 搜索"designer",出现图标表示成功。

如果没有,可以使用下面链接下载安装包,一键安装即可,安装成功后,会直接弹出来该工具。

https://build-system.fman.io/qt-designer-download

2.2 Pycharm配置

python语言开发,大部分使用Pycharm集成开发工具,这里在Pycharm工具中配置QT designer外部工具,在工程开发中让界面设计和解析变得容易。

打开Pycharm,File -> Settings ->Tools -> External Tools,点击加号添加,Program我这里添加的是安装包路径,因为我安装了PyQt_tools,找不到designer。Working directory设置保存ui文件的文件,$FileDir$表示当前文件所在目录

全部设置完成以后,可在Tools ->External Tools中打开。

用designer设计好的界面,会以.ui文件形式保存,下次直接右击该文件,选择External Tools中的designer工具加载即可

保存界面的另一种方式,是将生成的.ui文件解析成python脚本,下次可以直接运行脚本文件,打开ui界面。这种方式一般在整个GUI界面设计完成后执行,当然也不失为学习编程式UGI的好办法。

解析需要用到另外一个工具pyuic,直接命令生成py文件,该工具在安装pyqt后自带,无需安装。

pyuic5 /untitled.ui -o output_ui.py

另一种方式,是将该工具配置到Pycharm中,和上面designer添加方式一样,填写信息如下。

3、界面设计介绍

打开外部工具,会弹出窗口提示,如果不想每次启动都弹,在该窗口左下角设置去掉即可。

先整体认识下designer工具,左侧是不同类型组件,右侧可查看ui结构以及设置每个组件的属性,中间灰色地带为画布。

3.1 组件

组件是构建图像界面基本的模块,pyqt提供了多种组件,这里介绍一些使用频率较高的组件

组件名功能
窗口组件Main Window用于创建应用程序的主窗口,包含额外功能,如菜单栏、工具栏、状态栏等
Widget通用窗口组件,无额外功能,可作为Main Window的子组件或容器小部件使用
菜单类MenuBar菜单栏
StatusBar状态栏
ToolBar工具栏
展示组件Label显示文本或图像
Progress Bar显示进度条
Graphics View显示图像,支持缩放平移以及交互
List View以列表形式展示多行数据
输入组件Line Eidt输入单行文本
Text Edit输入多行文本
按钮组件Push Button按钮
CheckBox复选框
RadioButton单选按钮,多选项中只允许选择一个

3.1.1 菜单类组件

菜单栏组件包含 菜单栏+状态栏+工具栏 三部分

在designer中,先创建一个主窗口, File->New->Main Window

查看主窗口右侧ui结构,自带的菜单栏,状态栏,缺少工具栏ToolBar,选中MainWindow右击添加

主窗口中双击Type Here,输入菜单栏的名称File,回车即可进入到二级菜单栏,我这创建了四个二级菜单项,如下图所示。三级菜单项创建,点击二级菜单项右侧蓝色加号创建。如果想在菜单上面添加分割线,选中菜单名右击 Insert separator。

  • Type Here:输入菜单名
  • Add Separator:添加分割线

工具栏按钮不同于普通按钮,本质上是动作Action,而菜单栏中的每个菜单项也是Action。在PyQt中,如果在菜单栏中已经创建了某项,比如open,此时open这个动作就已经存在了。

工具栏按钮是直接拖拽现有的动作Action生成的,所以菜单栏和工具栏中,只要是对应同一Action的按钮,响应操作是一样的。在这里,我理解的工具栏更像是快捷键,将菜单栏中较为重要的选项放在外面,便于用户操作,接下里演示如何拖拽生成。

右击选中ui结构中的工具栏(如果没有可添加),下面属性设置中选中QtoolBar,其中

  • movable:工具栏移动,默认选中,主窗口左侧会出现一列
  • allowedAreas:设置工具栏位置,左右上下均可

找到工具栏可拖拽放到上下左右那个位置都行,下图是放在左侧了。

接下来拖拽Action到工具栏,首先需打开动作编辑(上面总体介绍的图解哪里有),能看到刚才菜单栏中创建的四个菜单项的Action都已经存在了,用鼠标拖住向工具栏位置放。

拖拽都没成功过,手都酸了,一个也没拖进去。这里分享个比较容易拖拽的方式,调节工具栏的高度,怎么调节看下图,依次选中图中选项,设置工具栏的宽和高。

3.1.2 图标和快捷键设置

如果想为菜单栏设置快捷键以及图标,可在动作编辑器中,选中某个Action右击,Eidt。

如下图,快捷键哪直接按键盘就自动输入进去了,Icon图标设置右边下拉三角中,我用的是choose file选择文件。

为全部的Action设置完成以后,如下图右侧所示,这时候拖拽工具栏只有图标,菜单栏中文字,图标,快捷键信息都有,想查看,可用ctrl+r快捷键方式,预览整个界面效果。

切记,添加的图标文件一定要放在你的工程目录下,否则换台电脑找不到图标就报错了 ,解析成python文件后,看下代码,里面用的是绝对文件路径。

3.1.3 分页组件Tab Widget

PyQt中的Tab Widget组件,通过创建选项卡界面,允许在一个窗口中显示多个界面,并来回切换,接下来让我们看看如何实现。

使用designer工具,创建主窗口后,直接拖拽左侧容器组件中的Tab Widget组件,默认是创建两个选项卡的,如中间画布所示,右侧是属性设置中修改选项卡名字的位置。

如果想增加新的选项卡,选中其中一个选项卡,右击弹出属性设置,如下可在该选项卡前面或后面增加新的选项卡。

删除选项卡,依然是选中右击,如下图所示,右拉三角delet。

接下来大家在每个选项卡内 设计自己的界面了,每个界面也都是独立的。

3.2 整体框架

这部分介绍如何使用.py文件执行ui界面。

3.2.1 ui 解析py文件

使用designer设计界面后,保存为.ui文件,使用pyuic工具生成.py,可直接使用如下命令

pyuic5 /untitled.ui -o output_ui.py

这里生成为Mainform.py文件,着重介绍下Mainform.py文件的内容,里面定义了一个类Ui_MainWindow,两个方法setupUi,retranslateUi。用designer工具设计并解析的py文件,一般都是这样的结构模式。

在setupUi方法中,会看到很多组件的变量名,后续会引用这些组件变量做交互操作,大家要分的清自己不同组件名所对应界面的那个区域,尤其是同一种组件的多处使用,最好呢在designer设计中就按自己的想法定义每个组件的名称。

在designer设计过程中,可直接在对应组件的的属性设置中,修改objectName

3.2.2 主函数

解析后的Mainform.py文件,直接运行并不会弹出界面,需要加一些固定内容。

在同目录下,我新建了一个Main.py文件,接着填充该文件。

Main.py内容,首先,定义了一个主窗口类LMainWindow,继承基类QMainWindow,__init__方法中调用了基类的 __init__方法,初始化了 QMainWindow。(照抄即可)

from PyQt5.QtWidgets import *
from Mainform import Ui_MainWindow

class LMainWindow(QMainWindow):
    def __init__(self,parent = None):
        super(LMainWindow,self).__init__(parent)

其中,parent表示这个窗口没有指定父级窗口,可以独立存在。如果需要将它嵌入到其他窗口中,可以传递一个父级窗口作为parent参数。

 接下来定义了一个LMain类,主要是怕类名和文件名一样,所以前面加了个L,大家可自行命名。以下代码中总共包含了3个类函数,

from tkinter import filedialog
from PyQt5.QtWidgets import *
from Mainform import Ui_MainWindow
import sys
import tkinter as tk

class LMainWindow(QMainWindow):
    def __init__(self,parent = None):
        super(LMainWindow,self).__init__(parent)


class LMain():
    def __init__(self):
        self.__mainWindow = None
        self.__mainform = None

    def _init_mainWindow(self):
        "初始化主窗口"
        self.__mainWindow = LMainWindow()  # 主窗口
        self.__mainform = Ui_MainWindow()  # 主界面
        self.__mainform.setupUi(self.__mainWindow)    
   
   def run(self):
        #创建应用程序实例
        app = QApplication(sys.argv)
        #初始化主窗口
        self._init_mainWindow()
        #显示主窗口
        self.__mainWindow.show()
        #运行应用程序
        sys.exit(app.exec_())

if __name__ == '__main__':
    app = LMain()
    app.run()

初始化__init__自然无需多说,大家可根据自己的需求编写。

初始化主窗口_init_mainWindow,先实例化了上面定义的窗口类LMainWindow对象,后实例化了Mainform.py文件中的Ui_MainWindow界面对象,并主窗口类对象作为参数传递给界面对象中的setupUi函数,将界面和窗口关联起来,使得主窗口能将界面展示出来,这部分照抄就行

run函数,这部分也是照抄就行,都是打开应用程序的一些基本操作。

完成之后,执行Main.py文件,就会弹出咱们设计的ui界面了,此时点击任何按钮都不会有反应。

3.3 信号和槽

使用designer设计的UI,其中设计的动作、按钮等都是没有实际作用的,因为我们并未告诉它就或者设置它,触发后应该去做什么。这部分内容主要是讲解PyQt中的信号和槽机制,为设计的UI界面,加上实际的操作,做到真正的交互。

  • 信号(Signal):触发特定组件时发出的信号
  • 槽(Slot):接收信号后,调用执行的函数或方法

将信号与槽连接connect,组件(Action,Button等)被触发时,连接的槽函数将被调用执行。

3.2.1 自定义信号和槽

Action动作action_objectName.triggered.connect(槽函数);

Button按钮button_objectName.clicked.connect(槽函数);

3.4 交互实现

3.2小节,搭建好了打开ui界面的基本框架,这一部分内容则是为组件添加信号和槽函数,做到真正的交互。以下内容均添加在Main.py文件中得LMain类内。

这是我创建的ui,主要参考标注画框软件Labelimg的界面。

初始化界面如下,图中多创建了一个List View,大家创建一个就行。

当用户分别点击左侧的Open Dir和Save Dir后,会弹出一个对话框,让用户选择一个目录,并记录下该目录的路径,同步展示在右侧的ListView中。如下图所示。

实现代码如下,其中的组件名称可能需要更换。

from tkinter import filedialog
from PyQt5.QtCore import QStringListModel
from PyQt5.QtWidgets import *
from Mainform import Ui_MainWindow
import sys
import tkinter as tk

class LMainWindow(QMainWindow):
    def __init__(self,parent = None):
        super(LMainWindow,self).__init__(parent)


class LMain():

    def __init__(self):
        self.__mainWindow = None
        self.__mainform = None
        self.__opendir =None
        self.__savedir = None

    def _init_mainWindow(self):
        "初始化主窗口"
        self.__mainWindow = LMainWindow()  # 主窗口
        self.__mainform = Ui_MainWindow()  # 主界面
        self.__mainform.setupUi(self.__mainWindow)

    #打开文件动作的槽函数
    def _action_event_opendir(self,type):
        root = tk.Tk()
        root.withdraw()
        file_dir = filedialog.askdirectory()
        if type == 'opendir':
            self.__opendir = file_dir
            #更新显示内容
            self._init_UI(1)
        elif type == 'savedir':
            self.__savedir = file_dir
            self._init_UI(1)

    def _init_view_model(self):
        self.view_model = QStringListModel()

    def _init_UI(self,type):
        "不同状态的界面"

        #初始状态
        if type == 0:
            #设置显示的字符串内容     
            self.view_model.setStringList([])
            self.__mainform.listView.setModel(self.view_model)
        #点击Open Dir 动作后界面状态
        elif type == 1:
            #此时显示选择的opendir路径,和savedir路径
            printvalue = [self.__opendir,self.__savedir]
            self.view_model.setStringList(printvalue)
            self.__mainform.listView.setModel(self.view_model)


    def _init_mainForm_widget_event(self):
        "绑定组件事件"

        #绑定Action
        self.__mainform.actionOpen_DIR.triggered.connect(lambda :self._action_event_opendir('opendir'))
        self.__mainform.actionSave_Dir.triggered.connect(lambda :self._action_event_opendir('savedir'))


    def run(self):
        # 创建应用程序实例
        app = QApplication(sys.argv)
        self._init_mainWindow()

        self._init_view_model()
        self._init_UI(0)
        self._init_mainForm_widget_event()

        # 显示主窗口
        self.__mainWindow.show()
        # 运行应用程序
        sys.exit(app.exec_())


if __name__ == '__main__':
    app = LMain()
    app.run()
  • 20
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值