用PyQt写python界面和处理代码的一般流程
PyQt5
PyQt5是一个用于创建GUI应用程序的python库,基于Qt5,提供了丰富的类用于实现各种功能。使用Qt设计的界面跨平台可用(Windows、Linux、MacOS),主要包含以下模块:
QtCore
模块包含核心的非GUI功能。该模块用于时间、文件和目录、各种数据类型、流、网址、MIME类型、线程或进程。
QtGui
模块包含图形组件和相关的类,例如按钮、窗体、状态栏、工具栏、滚动条、位图、颜色、字体等。
QtNetwork
模块包含了网络编程的类,这些类允许编写TCP/IP和UDP的客户端和服务器,他们使网络编程更简单,更轻便。QtXml
包含使用XML文件的类,这个模块提供了SAX和DOM API的实现。
QtSvg
模块提供显示的SVG文件的类。可缩放矢量图形(SVG)是一种用于描述二维图形和图形应用程序的XML语言。
QtOpenGL
模块使用OpenGL库渲染3D和2D图形,该模块能够无缝集成Qt的GUI库和OpenGL库。
安装PyQt5
pip install PyQt5
安装PyQt5之后,就可以使用它提供的工具设计界面、运行代码了。其中最有用的组件是designer
和pyuic
。
designer
是一个图形界面,可以在其中设计你的应用程序,并保存为.ui
文件。
在designer中设计界面
启动designer,其界面如下:
首先选择图形界面的模板:对话框(Dialog)、主窗口(Main Window,有菜单栏)还是小部件(窗口部件等)。
然后点击“创建”,就可以得到一个基础界面。
这里以主窗口型应用程序为例。用户将所需的组件拖动放置到主窗口中;
单击菜单项输入菜单项名称,然后回车(如果不按回车,无法保存输入):
输入主菜单名称后,便可以编辑子菜单,如下图所示:
其操作和微软所提供的MFC的界面设计很像。很多人说MFC已经过时了,但我觉得它在Windows平台上依然很好用,且用法和Qt很相似,可以作为C++初学者的入门库。
对于主窗口中的菜单项或小部件,都自动产生了一个对象名称(objectName),如下图所示:
用户可以在右侧的对象查看器和属性编辑器中修改对象名称和其他属性,以便后续编程使用。属性中的objectName就是编程时调用的成员变量名。
设计完界面之后,一定记得保存。保存为.ui文件,方便复用。
将设计的界面导出为.py文件
首先,激活python环境。如果当前python环境已经安装PyQt5,则可以通过一句命令行获得.py文件:
pyuic5 -o 输出文件名.py 用户创建的界面文件.ui
或者也可以用designer
预览python代码,如下图所示:
可以将窗口中的代码保存到.py文件:
需要注意的是,这两种方式生成的代码有些微差异,体现在import的库上。第一种方式一般从PyQt5中引入库;第二种方式一般从PySide中引入库。
使用设计的界面
按照上述步骤,得到所设计界面的.py文件后,应如何使用这个界面呢?
假设所得的.py文件名为custom_gui.py
,其中实现了一个类UI_MainWindow
,在与它同级的文件夹新建一个test_gui.py
,输入如下内容:
from custom_gui import UI_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
# 可以在这里添加其他初始化代码
# 例如,连接信号槽、设置初始数据等
self.action_OpenFile.itemDoubleClicked.connect(self.openfile)
def openfile(self):
'''
选取一个文件夹路径
'''
dir_path = QFileDialog.getExistingDirectory(self, "Select a Dir")
if dir_path:
self.dir_name=dir_path
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
在上面的代码中,新创建了MainWindow
类继承我们设计的界面类Ui_MainWindow和QtWidgets.QMainWindow类(这种现象称为多重继承,子类兼有两个父类的方法),并且为文件-Open File菜单的单击信号添加了openfile槽函数,并在MainWindow
类的构造函数中连接了信号和槽。
扩展阅读:对比Qt的信号-槽机制和MFC的消息映射机制
请读大佬博客。
示例:基于PyQt的gif图播放器
参考知乎大佬的代码,少许改进来的:
from PyQt5.Qt import Qt
from PyQt5.QtGui import QMovie
from PyQt5.QtWidgets import QApplication,QFileDialog,QLabel,QPushButton,QWidget,QHBoxLayout,QVBoxLayout
import sys
class GifPlayerWindow(QWidget):
def __init__(self):
super(GifPlayerWindow, self).__init__()
self.movie = QMovie()
self.label = QLabel()
self.label.setMovie(self.movie)
self.label.setAlignment(Qt.AlignCenter)
self.select_file_btn = QPushButton('选择gif文件')
self.start_btn = QPushButton('开始')
self.pause_resume_btn = QPushButton('暂停')
self.stop_btn = QPushButton('停止')
self.speed_up_btn = QPushButton('加速')
self.speed_down_btn = QPushButton('减速')
self.select_file_btn.clicked.connect(self.select_gif)
self.start_btn.clicked.connect(self.control)
self.pause_resume_btn.clicked.connect(self.control)
self.stop_btn.clicked.connect(self.control)
self.speed_up_btn.clicked.connect(self.control)
self.speed_down_btn.clicked.connect(self.control)
h_layout = QHBoxLayout()
v_layout = QVBoxLayout()
h_layout.addWidget(self.select_file_btn)
h_layout.addWidget(self.start_btn)
h_layout.addWidget(self.pause_resume_btn)
h_layout.addWidget(self.stop_btn)
h_layout.addWidget(self.speed_up_btn)
h_layout.addWidget(self.speed_down_btn)
v_layout.addWidget(self.label)
v_layout.addLayout(h_layout)
self.setLayout(v_layout)
def select_gif(self):
file, _ = QFileDialog.getOpenFileName(self, "Select Config File(.txt)")
if file is None:
return
self.movie.setFileName(file)
self.movie.jumpToFrame(0)
def control(self):
if self.sender() == self.start_btn:
self.movie.start()
elif self.sender() == self.pause_resume_btn:
if self.pause_resume_btn.text() == '暂停':
self.movie.setPaused(True)
self.pause_resume_btn.setText('继续')
elif self.pause_resume_btn.text() == '继续':
self.movie.setPaused(False)
self.pause_resume_btn.setText('暂停')
elif self.sender() == self.stop_btn:
self.movie.stop()
self.movie.jumpToFrame(0)
elif self.sender() == self.speed_up_btn:
speed = self.movie.speed()
self.movie.setSpeed(speed * 2)
elif self.sender() == self.speed_down_btn:
speed = self.movie.speed()
self.movie.setSpeed(speed // 2)
if __name__ == "__main__":
app = QApplication([])
win = GifPlayerWindow()
win.show()
sys.exit(app.exec())
可以选择gif文件,然后播放它。效果如下:
图片来源github示例图