赞
踩
PyQt是一套Python的GUI开发框架,即图形用户界面开发框架.
Python中经常使用的GUI控件集有PyQt、Tkinter、wxPython、Kivy、PyGUI和Libavg
其中PyQt是Qt(c++语言实现的)为Python专门提供的扩展
Qt 是一个1991年由Qt Company开发的跨平台C++图形用户界面开发框架。
2008年,Qt Company被诺基亚公司收购,Qt也因此成为诺基亚旗下的编程语言工具。
2012年,Qt被Digia收购。
2014年4月,跨平台集成开发环境Qt Creator 3.1.0正式发布
信号/槽(signal/slot)
机制进行通信(其它语言采用回调方式)pip install PyQt5
安装PyQt5
pip install PyQt5-tools
安装Qt
工具软件pip install PyQt5-stubs
安装PyQt5语法检测包(可选)如果安装缓慢,请配置pip源:
pip config set global.index-url https://mirror.baidu.com/pypi/simple
- from PyQt5.QtWidgets import QApplication,QWidget
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
执行代码,就会显示PyQt5窗口:
PyQt中有非常多的功能模块,开发中最常用的功能模块主要有三个:
应用程序图标是一个小的图像,通常在标题栏的左上角显示。
- from PyQt5.QtWidgets import QApplication,QWidget
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 设置窗口标题
- w.setWindowTitle('窗口')
- # 设置窗口尺寸
- w.resize(400, 300)
- # 设置图标
- w.setWindowIcon(QIcon('qq.png'))
-
- w.setToolTip('这个一个气泡提示')
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
文本控件是QLabel
- from PyQt5.QtWidgets import QWidget, QApplication, QLabel
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('文本展示')
-
-
- label = QLabel()
- label.setText('第一个文本')
- # 将文本控件添加到窗口中
- label.setParent(w)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QLabel 控件既可以显示文本,也可以显示图片
- from PyQt5.QtWidgets import QWidget, QApplication, QLabel
- from PyQt5.QtGui import QPixmap
- import sys
-
-
- def init_widget(w: QWidget):
- # 修改窗口标题
- w.setWindowTitle('图片展示')
- # 展示图片
- label = QLabel()
- pixmap = QPixmap('img.png')
- label.setPixmap(pixmap)
- # 显示到窗口中
- label.setParent(w)
- # 改变窗口大小
- w.resize(pixmap.width(), pixmap.height())
-
-
- if __name__ == '__main__':
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
- init_widget(w)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QLineEdit控件可以输入单行文本
- from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QVBoxLayout
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
-
- def init_widget(w: QWidget):
- # 修改窗口标题
- w.setWindowTitle('单行输入框')
- # 设置窗口大小
- w.resize(480, 320)
-
- layout = QVBoxLayout()
- # 展示单行输入框
- edit = QLineEdit()
- # 设置输入框提示
- edit.setPlaceholderText('请输入用户名')
- # 设置文本
- edit.setText('张三')
- # 获取单选框的文字
- text = edit.text()
- print(text)
- # 设置输入框最大字符数
- edit.setMaxLength(10)
- layout.addWidget(edit)
-
- edit3 = QLineEdit("Password")
- edit3.setPlaceholderText('请输入密码')
- edit3.setEchoMode(QLineEdit.Password)
- layout.addWidget(edit3)
-
- w.setLayout(layout)
-
-
- if __name__ == '__main__':
- # 1.创建应用程序
- app = QApplication(sys.argv)
- # 2.创建窗口
- w = QWidget()
- init_widget(w)
- # 3.显示窗口
- w.show()
- # 4.等待窗口停止
- sys.exit(app.exec())
QLineEdit的方法
方法 | 说明 |
|
|
| 设置文本框浮显文字 |
| 设置文本框内容 |
| 设置文本框所允许输入的最大字符数 |
QTextEdit
控件用来输入多行文本
- from PyQt5.QtWidgets import QApplication,QWidget,QTextEdit
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
-
- # 修改窗口标题
- w.setWindowTitle('多行输入框')
- # 多行输入框
- edit = QTextEdit()
-
- # 设置提示内容
- edit.setPlaceholderText('请输入发表的内容')
- # 设置文本内容
- edit.setPlainText('武汉疫情')
- # 获取输入的内容
- print(edit.toPlainText())
- edit.clear()
-
- # 显示多行输入框
- edit.setParent(w)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QTextEdit的方法
方法 | 说明 |
| 设置多行文本框的文本内容 |
| 返回多行文本框的文本内容 |
| 设置多行文本框的内容为HTML文档 |
| 返回多行文本框的HTML文档内容 |
| 清空多行文本框的内容 |
常见的按钮实现类包括:QPushButton
、QRadioButton
和QCheckBox
QPushButton
是最普通的按钮控件,可以响应一些用户的事件
- from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
- import sys
-
-
- def func():
- print("按下按钮啦,火箭发射!")
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('普通按钮')
- # 显示普通按钮
- btn = QPushButton()
- # 添加按钮提示
- btn.setText('发射')
- # 给按钮添加点击事件
- btn.clicked.connect(func)
- # 展示按钮
- btn.setParent(w)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
信号和槽机制是 QT 的核心机制,应用于对象之间的通信
signal
会被emit
出来,slot
调用是用来响应相应的signal
的signal
(基本组件都有各自特有的预定义的信号)通过调用 QObject 对象的 connect 函数来将对象的信号与另外一个对象的槽函数相关联,当发射者发射信号时,接收者的槽函数将被调用
点击按钮,输出hello
- from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
- import sys
-
-
- # 槽函数
- def click():
- print('hello1')
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('信号和槽的绑定')
- # 添加按钮
- btn = QPushButton()
- btn.setText('点我')
- btn.setParent(w)
-
- # 绑定按钮点击的信号和处理的槽函数
- # 方式1:槽函数使用函数
- # clicked 信号
- # click定义的槽函数
- btn.clicked.connect(click)
- # 方式2:槽函数使用lambda表达式
- # 信号和槽函数参数必须要保持一致
- # 如果信号中参数有= 槽函数可以不用添加
- btn.clicked.connect(lambda: print('hello2'))
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
利用系统自带退出函数QApplication.quit
点击按钮,关闭窗口
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('使用系统的槽函数')
- # 创建按钮
- btn = QPushButton()
- btn.setText('关闭窗口')
- # 显示按钮
- btn.setParent(w)
-
- # 信号和槽绑定
- btn.clicked.connect(QApplication.quit) # 使用QApplication的quit方法
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
- from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QHBoxLayout
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('水平布局')
- """------------------ 创建按钮 ------------------"""
- btn1 = QPushButton('1')
- btn2 = QPushButton('2')
- btn3 = QPushButton('3')
- btn4 = QPushButton('4')
- btn5 = QPushButton('5')
- # 创建布局
- layout = QHBoxLayout()
- # 添加布局到窗口中
- w.setLayout(layout)
- # 按钮控件添加到布局中
- layout.addWidget(btn1)
- layout.addWidget(btn2)
- layout.addWidget(btn3)
- layout.addWidget(btn4)
- layout.addWidget(btn5)
-
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
- from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('竖直布局')
- w.resize(480, 240)
- """------------------ 创建并添加5个按钮 ------------------"""
- # 创建布局
- layout = QVBoxLayout()
- # 布局添加到窗口中
- w.setLayout(layout)
-
- # 控件添加到布局中
- layout.addWidget(QPushButton('1'))
- layout.addWidget(QPushButton('2'))
- layout.addWidget(QPushButton('3'))
- layout.addWidget(QPushButton('4'))
- layout.addWidget(QPushButton('5'))
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
- from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QFormLayout, QPushButton
- import sys
-
-
- def func():
- name = nameEdit.text()
- age = ageEdit.text()
- phone = phoneEdit.text()
- print("姓名:{} 年龄:{} 电话:{}".format(name, age, phone))
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
- # w.resize(480, 320)
-
- # 修改窗口标题
- w.setWindowTitle('表单布局')
- """------------------ 创建布局 ------------------"""
- layout = QFormLayout()
- # 添加到窗口中
- w.setLayout(layout)
-
- # 输入框
- nameEdit = QLineEdit()
- ageEdit = QLineEdit()
- phoneEdit = QLineEdit()
- btn = QPushButton('发送')
- # 信号和槽绑定
- btn.clicked.connect(func)
-
- # 添加到布局中
- layout.addRow('姓名', nameEdit)
- layout.addRow('年纪', ageEdit)
- layout.addRow('电话', phoneEdit)
- layout.addRow('', btn)
-
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
通过布局嵌套可以实现更加复杂的布局
- from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QHBoxLayout,QVBoxLayout,QFormLayout
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
-
- # 修改窗口标题
- w.setWindowTitle('嵌套布局')
-
- """------------------ 实现布局 ------------------"""
- # 整体水平布局
- wholeLayout = QHBoxLayout()
- # 添加整体布局
- w.setLayout(wholeLayout)
-
- # 每一部分布局
- layout1 = QHBoxLayout()
- layout2 = QVBoxLayout()
- layout3 = QVBoxLayout()
-
- # 添加到整体的布局中
- wholeLayout.addLayout(layout1)
- wholeLayout.addLayout(layout2)
- wholeLayout.addLayout(layout3)
-
- # 控件
- # 添加第一部分控件
- layout1.addWidget(QPushButton('1'))
- layout1.addWidget(QPushButton('2'))
- # 添加第二部分控件
- layout2.addWidget(QPushButton('3'))
- layout2.addWidget(QPushButton('4'))
- # 添加第三部分控件
- layout3.addWidget(QPushButton('5'))
- layout3.addWidget(QPushButton('6'))
- layout3.addWidget(QPushButton('7'))
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QRadioButton
是单选按钮,它提供了一组可供选择的按钮和文本标签,用户可以选择其中一个选项
单选框选中的信号是:toggled
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- import sys
-
-
- def func(checked):
- '''
- 状态变化的槽函数
- :param checked: 是否被选中
- :return:
- '''
- print('状态变化', checked)
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('单选框')
- """------------------ 创建布局 ------------------"""
- layout = QHBoxLayout()
- # 添加布局到窗口中
- w.setLayout(layout)
- # 创建两个单选框
- rb1 = QRadioButton('男')
- rb2 = QRadioButton('女')
- rb1.setChecked(True)
- # 添加到布局中
- layout.addWidget(rb1)
- layout.addWidget(rb2)
-
- # 绑定信号和槽
- rb1.toggled.connect(func)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QCheckBox
提供了一组带文本标签的复选框,用户可以选择多个选项
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import *
- import sys
-
-
- def func(state):
- # 判断是否选中
- if state == Qt.Checked: # 2
- print('选中')
- else: # 0
- print('未选中')
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('复选框')
- """------------------ 窗口布局 ------------------"""
- layout = QHBoxLayout()
- # 添加到窗口中
- w.setLayout(layout)
-
- # 控件
- label = QLabel()
- label.setText('谦哥的爱好:')
- ck1 = QCheckBox('抽烟')
- ck2 = QCheckBox('喝酒')
- ck3 = QCheckBox('烫头')
-
- # 选中第一个
- ck1.setChecked(True)
-
- # 添加控件到布局中
- layout.addWidget(label)
- layout.addWidget(ck1)
- layout.addWidget(ck2)
- layout.addWidget(ck3)
-
- # 绑定信号和槽
- ck1.stateChanged.connect(func)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
对话框是为了更好地实现人与程序的交互
对话框主要是完成特定场景下的功能,比如删除确认等
QDialog的子类有QMessageBox
、QFileDialog
、QFontDialog
、QInputDialog
等
QMessageBox是普通的对话框
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
-
- def deleteUser():
- # 弹出对话框,让用户确认
- result = QMessageBox.question(w, '提示', '确认要删除好朋友吗?',
- QMessageBox.Ok | QMessageBox.Cancel,
- QMessageBox.Cancel)
- if result == QMessageBox.Ok:
- print('确认删除')
- elif result == QMessageBox.Cancel:
- print('取消删除')
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
- # 修改窗口标题
- w.setWindowTitle('对话框')
- """------------------ 创建按钮 ------------------"""
- btn = QPushButton('删除用户')
- # 显示控件
- btn.setParent(w)
-
- # 信号和槽绑定
- btn.clicked.connect(deleteUser)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
QIputDialog是输入对话框,由一个文本框和两个按钮(OK按钮和Cancel按钮)组成
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import QIcon
- import sys
-
- def func():
- str,success = QInputDialog.getText(w,'提示','请输入角色名称')
- if success:
- edit.setText(str)
-
-
- # 1.创建应用程序
- app = QApplication(sys.argv)
-
- # 2.创建窗口
- w = QWidget()
-
-
- # 修改窗口标题
- w.setWindowTitle('输入提示框')
- """------------------ 创建界面 ------------------"""
- layout = QHBoxLayout()
- # 添加布局
- w.setLayout(layout)
-
- # 控件
- btn = QPushButton('创建角色')
- edit = QLineEdit()
- # 控件添加到布局中
- layout.addWidget(btn)
- layout.addWidget(edit)
-
- # 信号和槽函数绑定
- btn.clicked.connect(func)
-
- # 3.显示窗口
- w.show()
-
- # 4.等待窗口停止
- sys.exit(app.exec())
写一个自定义类继承QWidget
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import *
- import sys
-
-
- class MyWindow(QWidget):
-
- def __init__(self, title):
- super().__init__()
- self.setWindowTitle(title)
-
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
-
- window = MyWindow("窗口标题")
- window.show()
-
- sys.exit(app.exec_())
通过继承QWidget
来实现窗体
在构造中,必须调用super
函数,否则将出行错误
- from PyQt5.QtWidgets import *
- from PyQt5.QtCore import *
- from PyQt5.QtGui import *
- import sys
-
-
- class MyWindow(QWidget):
-
- def __init__(self, title):
- super().__init__()
- self.setWindowTitle(title)
- self.init_ui()
-
- def init_ui(self):
- layout = QHBoxLayout()
- # ---------------------------------
-
- # 在这里初始化界面内容
-
- # ---------------------------------
- self.setLayout(layout)
-
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
-
- window = MyWindow("窗口标题")
- window.show()
-
- sys.exit(app.exec_())
使用信号和槽的好处在于,可以将代码分离成更小的、更可重用的部分,从而提高代码的可读性和可维护性。这种机制使得不同的对象之间可以进行通信,而不需要它们之间直接相互调用方法。
如果直接调用函数,会导致代码的紧密耦合,不利于代码的维护和扩展。此外,使用信号和槽也可以方便地实现多线程编程,因为它们可以在不同的线程之间进行通信。
使用信号和槽的目的:
PyQt中自定义信号和槽的步骤如下:
pyqtSignal()
方法来创建一个信号对象。pyqtSignal参数槽函数的参数类型@pyqtSlot()
装饰器将该方法注册为槽函数。信号.connect(槽函数)
方法将信号和槽连接起来。信号.emit()
方法来触发该信号,参数和槽函数参数一致。- from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
-
- class MyObject(QObject):
- # a. 定义一个自定义信号
- my_signal = pyqtSignal(str)
-
- # b. 定义一个槽函数
- @pyqtSlot(str)
- def my_slot(self, message):
- print("Received message: ", message)
-
- # 创建一个对象
- obj = MyObject()
-
- # b. 连接信号和槽
- obj.my_signal.connect(obj.my_slot)
-
- # c. 触发信号
- obj.my_signal.emit("Hello, World!")
首先定义了一个名为my_signal
的自定义信号。然后,我们定义了一个名为my_slot
的槽函数,并使用@pyqtSlot()
装饰器将其注册为槽函数。最后,我们创建了一个MyObject
对象,并将my_signal
信号连接到my_slot
槽函数。最后,我们通过调用emit()
方法来触发该信号,并将消息传递给槽函数。
当在不同的类中连接信号和槽时,需要使用QObject.connect()
方法来建立连接。假设我们有两个类Sender
和Receiver
,其中Sender
类定义了一个信号my_signal
,Receiver
类定义了一个槽函数my_slot
,那么连接过程如下:
- from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
-
- class Sender(QObject):
- my_signal = pyqtSignal(str)
-
- def send_data(self):
- data = "Hello, World!"
- self.my_signal.emit(data)
-
- class Receiver(QObject):
- @pyqtSlot(str)
- def my_slot(self, data):
- print("Received data: ", data)
-
- sender = Sender()
- receiver = Receiver()
-
- # 将信号连接到槽
- sender.my_signal.connect(receiver.my_slot)
-
- # 触发信号
- sender.send_data()
创建了两个类Sender
和Receiver
,并分别实例化了它们的对象sender
和receiver
。然后,我们使用connect()
方法将Sender
类中的信号my_signal
连接到了Receiver
类中的槽函数my_slot
。最后,我们通过调用send_data()
方法来触发信号,从而使得槽函数被调用,并输出接收到的数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。