一、 引言

在上节《第15.6节 PyQt5安装与配置》结束了PyQt5的安装和配置过程,本节将编写一个简单的PyQt5应用,介绍基本的PyQt5应用的文件组成及相关工具的使用。

本节的应用是要创建一个简单媒体播放器的界面,但暂不实现真正的播放器相关代码,只是点击时给出提示。

二、 创建工程

在PyCharm中新建MediaPlayer工程,进入界面后只有一个空的工程文件目录:



三、 图形界面设计

1、 通过tools->External Tools->PyQtDesigner打开图形设计界面



进入QtDesigner后出现如下界面:



2、 使用Widget新建一个窗口

新建窗口可以是Main Window,也可以是Widget,Main Window窗口比Widget窗口多了些组件如菜单等,如果不需要这些组件就可以使用Widget。我们在后面学习时再详细介绍。进入后初始窗口如图:



根据应用情况自己设置窗口相关属性:

objectname:UI_PlayerWin;

WindowModality:ApplicationModal;

windowTitle: 媒体播放器

windowIcon:选择一个叫“播放器.ico”图标文件

设置后界面如图:



3、 在增加一个带图标的播放按钮BtPlay(播放.ico)和一个播放文件名的行输入控件,最后图形化界面如下:



4、 建立播放事件

1)在UI_PlayerWin窗口新建一个成员函数playMedia

在UI_PlayerWin窗口鼠标右键选择change signals/slots,如图



出现UI_PlayerWin的slots 和signals编辑窗,在slots窗口下方点击加号按钮新建一个slot(就是UI_PlayerWin的一个成员函数),命名为:playMedia(),如图:



2)连接播放按钮BtPlay的click消息和UI_PlayerWin的槽函数playMedia()

点击菜单:Edit->Edit signals/Slots(或快捷键F4)后,在图形设计界面鼠标左键点中按钮BtPlay且不释放,往外拖拽到按钮外的UI_PlayerWin窗口区域,此时可以看到出现一根从按钮开始的连接曲线,如图:



松开鼠标右键弹出如下窗口:



左边窗口选择clicked(),右边选择playMedia(),这样就建立起来了鼠标点击播放按钮和UI_PlayerWin的槽函数playMedia()之间的连接。

点击OK保存。

四、 将UI文件转换为Python代码文件

回到PyCharm下,可以看到工程下新增了UI_PlayerWin.ui文件,鼠标右键选择该文件,出现浮动菜单,选择External Tools->PyUIC,如下图:



选择PyUIC后执行将ui文件转换成py文件,转换完成后在工程文件中增加了对应的py文件,如下图:



至此完成了UI界面文件的设计及转换。

五、 创建应用主程序

1、 选择工程(名MediaPlayer),鼠标右键后出现浮动菜单,选择:File->New Python file,出现如下弹窗:



在Name部分填入工程名字 “MediaPlayer”后,鼠标双击下面的Python file,出现Python文件编辑窗口,如图:



2、 在MediaPlayer.py中构建主程序框架

1)导入相关系统库

import sys

from PyQt5 import QtWidgets

from PyQt5.QtWidgets import QMessageBox

2)导入自己编写的UI界面类

from UI_PlayerWin import Ui_UI_PlayerWin

3)定义主窗口类

这里的主窗口类是从图形界面设计生成的窗口类的一个派生子类,在图形界面设计并通过PyUIC转换的窗口类中只是定义了窗口的界面、对应的信号和槽的连接,但没有实现槽函数具体应用代码,而本步骤定义的主窗口类通过实现槽函数来实现真正的应用代码,这个步骤有多种实现方法,老猿推荐用以下分步骤:

a) 主窗口类从UI界面类和QtWidgets.QWidget派生

class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin):

注意:这里的QtWidgets.QWidget是因为在定义图形界面主窗口时,选择的窗口类型是QWidget,如果是其他类型需要更换成对应类型。

b) 定义构造方法

构造方法至少需要调用父类的构造方法和UI界面类的setupUi方法(在老点的PyQt5的版本中,可能叫initUI方法),setupUi方法是所有Qt图形界面UI文件转换成Python代码后都有的方法,其功能就是完成图形界面初始化。

c) 实现槽函数

在Qt和PyQt中,信号相当于事件如鼠标点击等,但比一般的事件范围更大,可以自定义事件。槽相当于一个类的方法。连接信号和槽,就是相当于将图形界面中某对象的事件和某个类的某个成员方法进行绑定,当事件发生时就会触发对应类的对象方法的调用。

在UI图形界面设计时通过连接信号和槽,就为事件响应定义了执行的方法,但在图形界面中并不支持槽对应方法的代码编写,而如果直接修改图形界面转换的py文件,图形界面修改ui文件再次转换成py文件时,所有手动修改代码都会被覆盖。为了解决这个问题,通过在本部分继承图形界面及信号和槽的绑定,同时实现槽对应方法就完美的解决了这个问题,这样图形界面的修改不会影响真正执行的逻辑,而执行逻辑的修改也不会影响图形界面,真正做到了界面和逻辑的分离。

d) 类的完整定义代码

class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin):
def __init__(self):
super(MediaPlayerWin,self).__init__()
self.setupUi(self) #实现pushButton_click()函数,textEdit是我们放上去的文本框的id
def playMedia(self):
QMessageBox.information(self, "播放提示", "即将播放:"+self.lineEdit.text())

4)编写主程序执行代码

这部分主要是要遵循PyQt5主程序的通用规范代码,包括:

a) 创建应用实例:

app = QtWidgets.QApplication(sys.argv)

每一个pyqt程序必须创建一个application对象,sys.argv是命令行参数,可以通过命令启动的时候传递参数。

b) 初始化主程序窗口并显示:

mainwin = MediaPlayerWin()
mainwin.show()

注意: mainwin是主窗口应用名字,可以为自己想要的名字。这里的主程序窗口就是主窗口类的一个实例。

c) 事件处理开始,进入程序主循环

sys.exit(app.exec_())

主循环程序的任务就是等待事件,并把事件通过信号和槽的连接关系发送给指定应用处理。当调用app.exit()或者程序因为各种原因被破坏后,使用sys.exit()关闭程序,并释放内存资源。

d) 完整的主程序执行代码如下:

if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainwin = MediaPlayerWin()
mainwin.show()
sys.exit(app.exec_())

六、 代码执行截图



七、 本节相关的代码文件

  1. MediaPlayer.py
# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMessageBox
from UI_PlayerWin import Ui_UI_PlayerWin class MediaPlayerWin(QtWidgets.QWidget,Ui_UI_PlayerWin):
def __init__(self):
super(MediaPlayerWin,self).__init__()
self.setupUi(self) #实现pushButton_click()函数,textEdit是我们放上去的文本框的id
def playMedia(self):
QMessageBox.information(self, "播放提示", "即将播放:"+self.lineEdit.text()) if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainwin = MediaPlayerWin()
mainwin.show()
sys.exit(app.exec_())
  1. UI_PlayerWin.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UI_PlayerWin</class>
<widget class="QWidget" name="UI_PlayerWin">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>406</width>
<height>121</height>
</rect>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>媒体播放器</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../../资源/播放器.ico</normaloff>../../资源/播放器.ico</iconset>
</property>
<widget class="QPushButton" name="BtPlay">
<property name="geometry">
<rect>
<x>140</x>
<y>80</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>播 放</string>
</property>
<property name="icon">
<iconset>
<normaloff>../../资源/播放.ico</normaloff>../../资源/播放.ico</iconset>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>20</x>
<y>50</y>
<width>351</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>C:\temp\云朵-我的楼兰.mp3</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>13</x>
<y>20</y>
<width>221</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>请输入要播放的媒体文件名:</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>BtPlay</sender>
<signal>clicked()</signal>
<receiver>UI_PlayerWin</receiver>
<slot>playMedia()</slot>
<hints>
<hint type="sourcelabel">
<x>142</x>
<y>88</y>
</hint>
<hint type="destinationlabel">
<x>193</x>
<y>126</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>playMedia()</slot>
</slots>
</ui>
  1. ui文件转换生成的py文件
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'UI_PlayerWin.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_UI_PlayerWin(object):
def setupUi(self, UI_PlayerWin):
UI_PlayerWin.setObjectName("UI_PlayerWin")
UI_PlayerWin.setWindowModality(QtCore.Qt.ApplicationModal)
UI_PlayerWin.resize(406, 121)
UI_PlayerWin.setMouseTracking(True)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("../../资源/播放器.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
UI_PlayerWin.setWindowIcon(icon)
self.BtPlay = QtWidgets.QPushButton(UI_PlayerWin)
self.BtPlay.setGeometry(QtCore.QRect(140, 80, 75, 23))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap("../../资源/播放.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.BtPlay.setIcon(icon1)
self.BtPlay.setObjectName("BtPlay")
self.lineEdit = QtWidgets.QLineEdit(UI_PlayerWin)
self.lineEdit.setGeometry(QtCore.QRect(20, 50, 351, 20))
self.lineEdit.setObjectName("lineEdit")
self.label = QtWidgets.QLabel(UI_PlayerWin)
self.label.setGeometry(QtCore.QRect(13, 20, 221, 20))
self.label.setTextFormat(QtCore.Qt.RichText)
self.label.setObjectName("label") self.retranslateUi(UI_PlayerWin)
self.BtPlay.clicked.connect(UI_PlayerWin.playMedia)
QtCore.QMetaObject.connectSlotsByName(UI_PlayerWin) def retranslateUi(self, UI_PlayerWin):
_translate = QtCore.QCoreApplication.translate
UI_PlayerWin.setWindowTitle(_translate("UI_PlayerWin", "媒体播放器"))
self.BtPlay.setText(_translate("UI_PlayerWin", "播 放"))
self.lineEdit.setText(_translate("UI_PlayerWin", "C:\\temp\\云朵-我的楼兰.mp3"))
self.label.setText(_translate("UI_PlayerWin", "请输入要播放的媒体文件名:"))

本节详细介绍了一个PyQt5程序的构建过程,本来想将资源转换的过程加上来,但直接使用图标文件的方式无需进行此转换,老猿以后再研究清楚之后单独补充介绍。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036

请大家多多支持,点赞、评论和加关注!谢谢!

第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍的更多相关文章

  1. 第15.8节 PyQt入门学习:Designer的界面功能介绍

    进入Qt Designer以后,打开或新建一个ui文件,Qt Designer窗口展示的页面如下图所示: 老猿将界面各部分使用红色数字进行标记,按照数字顺序各区域对应功能分别为: 1.界面元素控件区域 ...

  2. 第二章、PyQt5应用构建详细过程介绍

    老猿Python博文目录 老猿Python博客地址 一.引言 在上节<第一章.PyQt的简介.安装与配置>介绍了PyQt5及其安装和配置过程,本节将编写一个简单的PyQt5应用,介绍基本的 ...

  3. 第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤

    在使用Qt Designer进行GUI设计时,一般常规的步骤都是差不多的,主要步骤包括新建显示窗口.在窗口上按照规划的布局放置组件.设置初始化组件的属性.定义信号和槽函数的连接,一般后三步是每增加一个 ...

  4. 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...

  5. 第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研 ...

  6. 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...

  7. 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

    老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...

  8. 第15.36节 PyQt(Python+Qt)入门学习:containers容器类部件QFrame框架部件介绍

    一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有如下: 容器中的Frame为一个矩形的框架对象,对应类QFrame,QFrame类是PyQt中带框架 ...

  9. 第15.30节 PyQt编程实战:通过eventFilter监视QScrollArea的widget()的Paint消息画出scrollAreaWidgetContents的范围矩形

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 在<PyQt(Python+Qt)学习随笔:QScrollArea滚动区域详解> ...

随机推荐

  1. C# 集合类(三)

    C# 集合类自己经常用到: 数组(Array).动态数组(ArrayList).列表(List).哈希表(Hashtable).字典(Dictionary),对于经常使用的这些数据结构,做一个总结,便 ...

  2. 《我想进大厂》之Java基础夺命连环16问

    说好了面试系列已经完结了,结果发现还是真香,嗯,以为我发现我的Java基础都没写,所以这个就算作续集了,续集第一篇请各位收好. 说说进程和线程的区别? 进程是程序的一次执行,是系统进行资源分配和调度的 ...

  3. MSSQL sql numeric转字符串显示不补0

    由于工作中需要把numeric转字符串显示,但是有一个问题会自动补0. DECLARE @f NUMERIC(18,4)=1.1200, @str VARCHAR(50) SELECT CAST(@f ...

  4. 内核补丁热更新ceph内核模块

    前言 内核模块的更新一般需要卸载模块再加载,但是很多时候使用场景决定了无法做卸载的操作,而linux支持了热更新内核模块的功能,这个已经支持了有一段时间了,一直没有拿ceph的相关模块进行验证 准备工 ...

  5. ListView的HeaderView包含的GridView滑动隐藏后无法点击问题分析

    目录 1 现象 2 问题分析 2.1 滑动前 2.2 滑动后 2.3 mDataChanged赋值为true的位置 2.3 GridView直接作为ListView的HeaderView为什么可以滑动 ...

  6. Java 实例化接口或抽象类

    1. 实例化接口: 某一天,我们想通过反射调用一个类的方法,但发现方法参数中有一个接口,我们都知道接口不能被实例化,这该怎么办呢? 举例: public class TestLib { public ...

  7. LTMU论文解析

    LTMU 第零部分:前景提要 一般来说,单目标跟踪任务可以从以下三个角度解读: A matching/correspondence problem.把其视为前后两帧物体匹配的任务(而不考虑在跟踪过程中 ...

  8. 我的开源经历:为了方便处理三方 HTTP 接口而写的 Java 框架

    缘起 我以前公司需要在 Java 后台调用许多第三方 HTTP 接口,比如微信支付.友盟等等第三方平台. 公司内部还有很多服务是用世界最好语言写的,接口自然也只能通过 HTTP 接口来调用.于是日积月 ...

  9. laravel 验证器使用

    1.前后端不分离 (form表单提交) 控制器定义验证规则 <?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Req ...

  10. 建议收藏!2020阿里面试题(JVM+Spring Cloud+微服务)上

    前言 对于大厂面试,我想要强调的一点就是心态真的很重要,是决定你在面试过程中发挥的关键,若不能正常发挥,很可能就因为一个小失误与offer失之交臂,所以一定要重视起来.另外提醒一点,充分复习,是消除你 ...