上篇文章中学习的wxPython用户界面,没有拖拽组件等操作,不是很方便,下面来看个更加强大的GUI==>PyQt系列,拥有拖拽组件界面,这样设计界面就显得非常简单与方便了。Qt库由 Riverbank Computing开发,是最强大的GUI库之一 ,同样也是可以跨平台运行。
安装比较简单,建议习惯带上镜像地址,下载速度非常快。
pip install PyQt6 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
我们来测试下PyQt6的安装是否成功:
import sys
from PyQt6 import QtWidgets
app = QtWidgets.QApplication(sys.argv)
win = QtWidgets.QWidget()
win.resize(400,400)
win.setWindowTitle("寅恪光潜")
win.show()
sys.exit(app.exec())
发现报错了,不能引入这个类型
RuntimeError: PyQt6.QtWidgets cannot import type '�bz��' from PyQt6.QtCore、
我这里安装的时候没有指定版本,现在重装,确保两者版本一致:
pip uninstall PyQt6
pip uninstall PyQt6-tools
pip install PyQt6==6.0.2 PyQt6-tools==6.0.2.3.2 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
再次测试就没有问题了,所以这里对版本有一致的要求,故指定版本号来下载
安装好了之后,我们需要找到designer.exe(图形界面开发工具Qt Designer),不过在PyQt5之后就没有直接提供了,需要自行安装,同样使用pip安装,推荐带上镜像地址
pip install PyQt6-tools -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
个人建议安装在虚拟环境中,比如本人的地址:
activate myd2l
(myd2l) C:\Users\Tony>
#然后在这个里面去找Qt设计师
D:\Anaconda3\envs\myd2l\Lib\site-packages\qt6_applications\Qt\bin\designer.exe
双击打开designer看下是个什么界面:
这个界面就是QT设计师的界面,里面有各种组件随你拖拽,然后我们创建一个窗口,加点东西,保存下,看到后缀是.ui的文件,也就是用户界面文件的意思
上面的界面我们保存为tony.ui文件,我在里面加了文本输入框和按钮,然后打开ui文件可以看到里面是xml格式的内容:
MainWindow
0
0
800
600
MainWindow
70
90
55
16
用户名
120
190
75
24
登录
140
90
113
20
140
140
113
20
QLineEdit::Password
70
140
55
16
密 码
0
0
800
22
寅恪光潜
这种界面文件要应用到Python中,我们需要把它转成.py格式文件,通过如下命令:
python -m PyQt6.uic.pyuic tony.ui -o tony.py
转成功之后,将生成一个tony.py,然后我们打开之后,在其代码最后加上以下代码即可:
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec())
原来的ui转换之后的代码如下[也就是Ui_MainWindow这个class是我们通过pyuic将ui界面生成的python代码]
tony.py
# Form implementation generated from reading ui file 'tony.ui'
#
# Created by: PyQt6 UI code generator 6.0.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(400, 400)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(70, 90, 55, 16))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(120, 190, 75, 24))
self.pushButton.setObjectName("pushButton")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(140, 90, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(140, 140, 113, 20))
self.lineEdit_2.setEchoMode(QtWidgets.QLineEdit.EchoMode.Password)
self.lineEdit_2.setObjectName("lineEdit_2")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(70, 140, 55, 16))
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menubar.addAction(self.menu.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "用户名"))
self.pushButton.setText(_translate("MainWindow", "登录"))
self.label_2.setText(_translate("MainWindow", "密 码"))
self.menu.setTitle(_translate("MainWindow", "寅恪光潜"))
这种自动生成的代码,不要去编辑,也不需要编辑,因为界面的修改,再次生成时,会自动覆盖原来的代码,所以我们另外写代码,不要在自动生成的代码里面去写。
我们新建一个tonytest.py文件,界面代码和自己写的代码分开来,便于后期修改。
tonytest.py
from tony import Ui_MainWindow
from PyQt6 import QtCore, QtGui, QtWidgets
import sys
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec())
导入来自tony.py里的Ui_MainWindow类即可
我们来点击“登录”按钮,调用一个方法看看效果怎么样,我们重新写一个class来实现界面需要的逻辑,这个跟做Web开发一个道理,设计的负责界面的设计,需要实现的功能就交给逻辑代码来处理,各自分工。
from tony import Ui_MainWindow
from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QMessageBox
import sys
class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent=parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.btnClicked) # 登录按钮点击绑定事件
def btnClicked(self):
msg = f'Hello {self.sender().text()}'
self.statusBar().showMessage(msg)
QMessageBox.information(self, 'hi', msg)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MyWindow = MyWindow()
MyWindow.show()
sys.exit(app.exec())
可以看到,点击登录按钮之后,将在状态栏显示信息和弹出框显示自定义信息。如下图:
我们来做一个视频转换的小栗子,将一些常见的视频格式转成mp4:
界面设计好了之后,将video.ui界面文件转成python文件video.py:
python -m PyQt6.uic.pyuic video.ui -o video.py
然后写逻辑代码如下,导入上面生成的video.py里面的库:
from video import Ui_MainWindow
from PyQt6 import QtWidgets
from PyQt6.QtWidgets import QFileDialog,QMessageBox
import sys,os,datetime
class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent=parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.btnClicked)
self.pushButton_2.clicked.connect(self.btnChangeMP4)
def btnClicked(self):
file_name = QFileDialog.getOpenFileName(self, "选择视频", "./", "视频 (*.mkv *.rmvb *.avi)")
self.fname= file_name[0]
def btnChangeMP4(self):
newfname=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
os.system('ffmpeg -i '+self.fname+' -c copy '+newfname+'.mp4')
QMessageBox.information(self, 'hi', '格式转换成功')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
MyWindow = MyWindow()
MyWindow.show()
sys.exit(app.exec())
可以看出转换视频,我这里做了两步
第一步使用QFileDialog.getOpenFileName获取选择的视频文件名称
第二步使用系统的命令行,利用ffmpeg来做视频转换。
其中需要使用到ffmpeg,点击下载