来源
http://www.python3.vip/tut/py/gui/qt_02/
分析
我们通过刚刚的代码,其实已经是将程序的界面创建出来了,但是实质上这个程序的功能我们还没有实现。
这个程序的功能
当前的问题
这个程序的功能应该如何才能和这个图形界面结合起来?
当我们点击【统计】这个按钮的时候,我们怎么样才能够告知程序:用户点击了【统计】按钮
我们不能在程序刚运行的时候就实现统计功能,因为用户还没有输入内容呢。
那么应该什么时候才能够统计呢?只有在用户点击【统计】按钮之后,程序才会执行统计这块功能的代码
关键是,程序是如何知道用户点击了【统计】按钮的?
尝试解决问题
对问题进行分析
在 Qt 系统中, 当界面上一个控件被操作时,比如 被点击、被输入文本、被鼠标拖拽等, 就会发出信号
,英文叫signal
。就是表明一个事件(比如被点击、被输入文本)发生了。
我们现在就是要告诉我们的程序:用户的操作发生了。
操作发生之后的处理
我们可以预先在代码中指定 处理这个 signal
的函数,这个处理signal
的函数 叫做slot
。
def handleCalc():
print('统计按钮被点击了')
也就是说,当用户点击【统计】按钮的时候,我希望这个程序能够执行这个函数来处理。
逐步实现操作
最关键的事情:当我们点击【统计】的时候,我们是如何告诉程序,使用什么函数来处理呢?
我们需要在代码中写一段代码指定,当【统计】按钮被点击的时候,这个信号发生的时候,程序会调用我们指定的方法来处理。
button.clicked.connect(handleCalc)
button.clicked.connect(handleCalc)
"""
指定如果发生了 button 按钮被点击 的事情,需要让 handleCalc 来处理
也就是用 handleCalc 来处理 这个按钮被点击之后的操作
处理信号的函数在QT上有一个术语叫做“slot”(槽)
"""
尝试运行
我们每点击一次【统计】按钮,在终端上就会打印出我们指定的内容
初步解决问题
我们应该如何从文本框中获取内容
我们需要了解各种控件,它里面提供了什么样的方法可以获取文本内容?
也就是说我们需要去查找文档了。
http://www.python3.vip/tut/py/gui/qt_05_1/#%E6%96%B9%E6%B3%95%E8%8E%B7%E5%8F%96%E6%96%87%E6%9C%AC
方法:获取文本
通过 text 方法获取编辑框内的文本内容,比如
text = edit.toPlainText()
如何使用代码实现程序的功能
def handleCalc():
# 获取文本
info=textEdit.toPlainText() # 将文本内容获取过来,然后存在一个变量中
# 薪资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}'''
)
运行程序
将代码封装到类中
代码预览
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit,QMessageBox
class Stats():
def __init__(self):
self.window = QMainWindow()
self.window.resize(500, 400)
self.window.move(300, 300)
self.window.setWindowTitle('薪资统计')
self.textEdit = QPlainTextEdit(self.window)
self.textEdit.setPlaceholderText("请输入薪资表")
self.textEdit.move(10, 25)
self.textEdit.resize(300, 350)
self.button = QPushButton('统计', self.window)
self.button.move(380, 80)
self.button.clicked.connect(self.handleCalc)
def handleCalc(self):
info = self.textEdit.toPlainText()
# 薪资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(self.window,
'统计结果',
f'''薪资20000 以上的有:\n{salary_above_20k}
\n薪资20000 以下的有:\n{salary_below_20k}'''
)
app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()
执行程序
程序总结
封装前的代码
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit,QMessageBox
# QtWidgets是PySide2中一部分的内容,它专门负责带有控件的窗口
# QApplication:应用程序
# QMainWindow:主窗口
# QPushButton:按钮
# QPlainTextEdit:纯文本的编辑框
def handleCalc():
# 获取文本
info=textEdit.toPlainText() # 将文本内容获取过来,然后存在一个变量中
# 薪资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}'''
)
# QMessageBox
# 统计完之后会弹出一个对话框
app = QApplication([]) # 实例化一个对象
# QApplication提供了整个图形界面程序的底层管理功能
# 比如:初始化、程序入口参数的处理,用户事件(对界面的点击、输入、拖拽)分发给各个对应的控件,等等…
# 初始化:为了图形用户界面,它需要初始一些资源,操作系统要申请一些资源的处理
# 用户事件:用户对界面的点击、输入、拖拽,这些都是属于用户事件,它需要把这些事件分发给各个控件
# 比如说你在哪个区域点击的,这个区域属于哪个控件管理
"""因为QApplication需要做这么多重要的操作,所以我们必须在任何界面控件对象创建前,先创建它。
至于这里面的参数,我们可以先填一个空值"""
"""主窗口对象"""
window = QMainWindow()
# 创建一个主窗口对象
# 注意:直到目前为止的创建都还没有显示在界面上,只是我们先把即将要显示在界面上的主窗口先申请一下,先定义一下它的外观和其他的几个属性,但是代码执行到现在为止,还没有生成这个主窗口对象显示在界面上
window.resize(800, 600)
# 决定了这个主窗口对象的大小
# (宽度,高度)单位:px,例如:(500,400)表示:宽度:500px,高度:400px
window.move(1000, 110)
# 控制这个主窗口待会在显示的时候会出现在用户的显示器的什么位置
# 具体算法是程序的左上角和显示器的左上角的相对位置
# (在x轴上的距离,在y轴上的距离)单位:px
window.setWindowTitle('薪资统计')
# window.setWindowTitle(string)表示:将string中的内容设置在程序的标题栏上
"""纯文本输入的控件"""
textEdit = QPlainTextEdit(window)
# 实例化一个对象
# QPlainTextEdit:纯文本的控件
# 参数:window 表示指定我们当前控件的副窗口是window,也就是在副窗口上创建这个控件
# 简单说就是在主窗口对象上创建一个纯文本输入的区域
textEdit.setPlaceholderText("请输入薪资表")
# 这个控件的方法叫做:setPlaceholderText
# setPlaceholderText(string):就是在这个纯文本输入的控件中我们预先定义好的具有提示性语言的文本,其中string为提示性文本的内容
# 这块区域中没有输入内容:显示提示性文本
# 这块区域中我们输入了内容:显示我们输入的内容,提示性文本自动消失
textEdit.move(30,50)
# 设置这块区域在整个主窗口对象中的位置
# 如果说一个控件存在着副窗口,那么这个命令就表示这块区域的左上角和这个副窗口区域的左上角的相对位置
# 因为现在这个控件的副窗口就是我们的主窗口对象
# 所以这段代码在这里表示:这块区域的左上角和整个主窗口左上角的相对位置,其中要注意:这里的主窗口不包括标题栏
textEdit.resize(300,350)
# 指定这个控件区域的大小
# (宽度,高度)单位:px
"""按钮控件"""
button = QPushButton('统计', window)
# 实例化一个按钮对象
# button = QPushButton(按钮上显示什么文本,设置这个控件的副窗口(也就是在这个副窗口区域上创建这个按钮控件))
# 表示:在主窗口对象上创建一个按钮,这个按钮上显示着“统计”这段内容
button.move(380,80)
# 在这里表示这个按钮区域的左上角和整个主窗口的左上角的相对位置
# 因为这个按钮区域的副窗口是整个主窗口
button.clicked.connect(handleCalc)
"""
指定如果发生了 button 按钮被点击 的事情,需要让 handleCalc 来处理
也就是用 handleCalc 来处理 这个按钮被点击之后的操作
处理信号的函数在QT上有一个术语叫做“slot”(槽)
"""
window.show()
# 表示将window展示在界面上
# 注意:到这里程序还没有结束,因为如果没有下一行代码,那这个程序执行到这里就一闪而过就没了
app.exec_()
# 表示:进入了事件处理循环
# 也就是说我们当前的这个带有界面的程序执行到现在的这行代码的时候就说明这个程序一直在循环,等待用户对于这个界面的操作(这其实就是事件),然后它会对用户的事件作出反应
# 注意:这是一个死循环,只要我们不是人为地关闭这个窗口,它是永远也不会退出的
# 注意:这段代码很重要,如果没有这段代码,那么我们的程序一跑到这里就会自动结束,这句才是真正的消息的处理
封装后的代码
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit,QMessageBox
class Stats():
def __init__(self):
self.window = QMainWindow()
self.window.resize(500, 400)
self.window.move(300, 300)
self.window.setWindowTitle('薪资统计')
self.textEdit = QPlainTextEdit(self.window)
self.textEdit.setPlaceholderText("请输入薪资表")
self.textEdit.move(10, 25)
self.textEdit.resize(300, 350)
self.button = QPushButton('统计', self.window)
self.button.move(380, 80)
self.button.clicked.connect(self.handleCalc)
def handleCalc(self):
info = self.textEdit.toPlainText()
# 薪资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(self.window,
'统计结果',
f'''薪资20000 以上的有:\n{salary_above_20k}
\n薪资20000 以下的有:\n{salary_below_20k}'''
)
app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()