Python图形界面开发的几种方案
如果用 Python 语言开发 跨平台 的图形界面的程序,主要有3种选择:
Tkinter
基于Tk的Python库,这是Python官方采用的标准库,优点是作为Python标准库、稳定、发布程序较小,缺点是控件相对较少。
wxPython
基于wxWidgets的Python库,优点是控件比较丰富,缺点是稳定性相对差点、文档少、用户少。
PySide2、PyQt5
基于Qt 的Python库,优点是控件比较丰富、跨平台体验好、文档完善、用户多。
缺点是 库比较大,发布出来的程序比较大。
PySide2、PyQt5 简介
PySide2、PyQt5 都是基于著名的 Qt 库。
Qt库里面有非常强大的图形界面开发库,但是Qt库是C++语言开发的,PySide2、PyQt5可以让我们通过Python语言使用Qt。
但是 PySide2、PyQt5 这两者有什么区别呢?
可以形象地这样说: PySide2 是Qt的 亲儿子 , PyQt5 是Qt还没有亲儿子之前的收的 义子 (Riverbank Computing这个公司开发的)。
那为什么 PyQt5 这个义子 反而比 PySide2 这个亲儿子更出名呢?
原因很简单:PySide2 这亲儿子最近(2018年7月)才出生。
但是亲儿子毕竟是亲儿子,Qt准备大力培养,PySide2 或许更有前途。
已经在使用 PyQt5 的朋友不要皱眉, 两个库的使用 对程序员来说,差别很小:它们的调用接口几乎一模一样。
如果你的程序是PyQt5开发的,通常只要略作修改,比如把导入的名字从 PyQt5 换成 PySide2 就行了。反之亦然。
报错
python文件没安装上(虚拟环境不对)
环境(解释器)不对
一个案例
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit, QMessageBox #导入几个控件(Widiget)
def handleCalc():
info = textEdit.toPlainText()
# 在 Qt 系统中, 当界面上一个控件被操作时,比如 被点击、被输入文本、被鼠标拖拽等, 就会发出 信号 ,英文叫 signal 。就是表明一个事件(比如被点击、被输入文本)发生了。
# 我们可以预先在代码中指定 处理这个 signal 的函数,这个处理 signal 的函数 叫做 slot 。
# 薪资20000 以上 和 以下 的人员名单
salary_above_20k = ''
salary_below_20k = ''
for line in info.splitlines():
if not line.strip():
continue
parts = line.split(' ')
# 去掉列表中的空字符串内容
parts = [p for p in parts if p]
name,salary,age = parts
if int(salary) >= 20000:
salary_above_20k += name + '\n'
else:
salary_below_20k += name + '\n'
QMessageBox.about(window,
'统计结果',
f'''薪资20000 以上的有:\n{salary_above_20k}
\n薪资20000 以下的有:\n{salary_below_20k}'''
)
app = QApplication([])
window = QMainWindow()
window.resize(500, 400) #窗口大小
window.move(300, 310)#窗口出现在显示器什么位置
window.setWindowTitle('薪资统计')#窗口标题
textEdit = QPlainTextEdit(window)#纯文本的编辑框
textEdit.setPlaceholderText("请输入薪资表")#提示文本(浅色)
textEdit.move(10,25)#编辑框的位置-相对于副窗口(window)
textEdit.resize(300,350)#编辑框的大小
button = QPushButton('统计', window)
button.move(380,80)
button.clicked.connect(handleCalc)#让 handleCalc 来 处理 button 被 点击的操作。
window.show()#show方法展现出来
app.exec_()#QApplicati进入事件处理循环(死循环)
QApplication 提供了整个图形界面程序的底层管理功能,比如:
初始化、程序入口参数的处理,用户事件(对界面的点击、输入、拖拽)分发给各个对应的控件,等等…
在 Qt 系统中,控件(widget)是 层层嵌套 的,除了最顶层的控件,其他的控件都有父控件。
QPlainTextEdit、QPushButton 实例化时,都有一个参数window,如下
QPlainTextEdit(window)
QPushButton('统计', window)
就是指定它的父控件对象 是 window 对应的QMainWindow 主窗口。
而 实例化 QMainWindow 主窗口时,却没有指定 父控件, 因为它就是最上层的控件了。
界面动作处理 (signal 和 slot)
当用户点击 统计 按钮时, 从界面控件 QPlainTextEdit 里面获取 用户输入的字符串内容,进行处理。
首先第一个问题: 用户点击了 统计 按钮,怎么通知程序? 因为只有程序被通知了这个点击,才能做出相应的处理。
在 Qt 系统中, 当界面上一个控件被操作时,比如 被点击、被输入文本、被鼠标拖拽等, 就会发出 信号 ,英文叫 signal 。就是表明一个事件(比如被点击、被输入文本)发生了。
我们可以预先在代码中指定 处理这个 signal 的函数,这个处理 signal 的函数 叫做 slot 。
比如,我们可以像下面这样定义一个函数
defhandleCalc():
print('统计按钮被点击了')
然后, 指定 如果 发生了button 按钮被点击 的事情,需要让 handleCalc 来处理,像这样
button.clicked.connect(handleCalc)
用QT的术语来解释上面这行代码,就是:把 button 被 点击(clicked) 的信号(signal), 连接(connect)到了 handleCalc 这样的一个 slot上
大白话就是:让 handleCalc 来 处理 button 被 点击的操作。
运行效果
Qt Designer
QT程序界面的 一个个窗口、控件,就是像上面那样用相应的代码创建出来的。
但是,把你的脑海里的界面,用代码直接写出来,是有些困难的。
很多时候,运行时呈现的样子,不是我们要的。我们经常还要修改代码调整界面上控件的位置,再运行预览。反复多次这样操作。
可是这样,真的…太麻烦了。
其实,我们可以用QT界面生成器 Qt Designer ,拖拖拽拽就可以直观的创建出程序大体的界面。
通过 Qt Designer 设计的界面,最终是保存在一个ui文件中的。
大家可以打开这个ui文件看看,就是一个XML格式的界面定义。
Windows下,运行 Python安装目录下 Scripts\pyside2-designer.exe 这个可执行文件
如果你安装的是pyqt5, 运行 Python安装目录下 Scripts\pyqt5designer.exe 这个可执行文件
ui文件的内容:
from PySide2.QtWidgets import QApplication, QMessageBox
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile
class Stats:
def __init__(self):
# 从文件中加载UI定义
qfile_stats = QFile("C:/Users/Miles/Desktop/qt学习/1/ui/stats.ui")
qfile_stats.open(QFile.ReadOnly)
qfile_stats.close()
# 从 UI 定义中动态 创建一个相应的窗口对象
# 注意:里面的控件对象也成为窗口对象的属性了
# 比如 self.ui.button , self.ui.textEdit
self.ui = QUiLoader().load(qfile_stats)
self.ui.button.clicked.connect(self.handleCalc)
def handleCalc(self):
info = self.ui.textEdit.toPlainText()
salary_above_20k = ''
salary_below_20k = ''
for line in info.splitlines():
if not line.strip():
continue
parts = line.split(' ')
parts = [p for p in parts if p]
name,salary,age = parts
if int(salary) >= 20000:
salary_above_20k += name + '\n'
else:
salary_below_20k += name + '\n'
QMessageBox.about(self.ui,
'统计结果',
f'''薪资20000 以上的有:\n{salary_above_20k}
\n薪资20000 以下的有:\n{salary_below_20k}'''
)
app = QApplication([])
stats = Stats()
stats.ui.show()
app.exec_()
关键的地方
至此,ui文件可单独设计