文章目录
- PyQt5
- 1. PyQt5的下载与安装
- 1.1 PyQt5介绍
- 1.2 windows PyQt5的安装
- 2.PyQt5基本UI
- 2.1 第一个PyQt程序
- 2.2 argv
- 2.3 模块介绍
- 3.基本UI
- 3.1 按钮QPushButton
- 3.2 文本QLabel
- 3.3 输入框
- 3.4 调整窗口大小
- 3.5 调整窗口显示屏幕中间
- 3.6 设置窗口icon
- 4.布局
- 4.1 QBoxLayout
- 4.1.1 垂直布局
- 4.1.2 水平布局
- 4.2 QGridLayout
- 网格布局
- 4.3 QFormLayout
- 4.4 抽屉布局
- 5. 窗口
- 5.1 分类
- 5.2 QWidget
- 5.2 QMainWindow
- 5.3 QDialog
- 6. 信号与槽
- 6.1 信号与槽介绍
- 6.2 案例
- 6.3 自定义信号
- 7.Qt Designer
- 7.1 介绍
- 7.2 下载
- 7.3 安装&运行
- 7.4 使用QT Designer
- 7.5 使用流程
PyQt5
1. PyQt5的下载与安装
1.1 PyQt5介绍
Qt(官方发音 [kju:t]
)是一个跨平台的C++开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序
Qt 是纯 C++ 开发的,正常情况下需要先学习C语言、然后在学习C++然后才能使用Qt开发带界面的程序
多亏了开源社区使得Qt 还可以用Python、Ruby、Perl 等脚本语言进行开发。
Qt 支持的操作系统有很多,例如通用操作系统 Windows、Linux、Unix,智能手机系统Android、iOS, 嵌入式系统等等。可以说是跨平台的
QT官网:https://doc.qt.io/qt-5/index.html
PyQt的开发者是英国的“Riverbank Computing”公司。它提供了GPL(简单的说,以GPL协议发布到网上的素材,你可以使用,也可以更改,但是经过你更改然后再次发布的素材必须也遵守GPL协议,主要要求是必须开源,而且不能删减原作者的声明信息等)与商业协议两种授权方式,因此它可以免费地用于自由软件的开发。
PyQt可以运行于Microsoft Windows、Mac OS X、Linux以及Unix的多数变种上。
PyQt是Python语言的GUI(Graphical User Interface,简称 GUI,又称图形用户接口)编程解决方案之一
可以用来代替Python内置的Tkinter
。其它替代者还有PyGTK
、wxPython
等,与Qt一样,PyQt是一个自由软件
文档相关地址:https://www.riverbankcomputing.com/software/pyqt/
比较不错的参考资料:https://wiki.python.org/moin/PyQt/Tutorials
-
Qt (C++ 语言 GUI )
-
PyQt = Python + Qt技术
-
Tkinter
Python官方采用的标准库,优点是作为Python标准库、稳定、发布程序较小,缺点是控件相对较少。
-
wxPython
基于wxWidgets的Python库,优点是控件比较丰富,缺点是稳定性相对差点、文档少、用户少。
-
PySide2、PyQt5
基于Qt 的Python库,优点是控件比较丰富、跨平台体验好、文档完善、用户多。
缺点是 库比较大,发布出来的程序比较大。
PyQt5 的开发者是英国的“Riverbank Computing”公司 , 而 PySide2 则是 qt 针对python语言提供的专门
1.2 windows PyQt5的安装
- 执行命令,允许创建虚拟环境
pip install virtualenv
pip install virtualenvwrapper-win
- 创建新的虚拟环境
mkvirtualenv -p python3 py3-qt --no-download
- 安装pyqt5(命令行)
workon py3-qt #切换到py3-qt环境
pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple
- 版本测试
# 如果执行成功,没有任何错误提示,则表明环境搭建成功
from PyQt5 import QtWidgets
# 当然也可以查看PyQt版本
from PyQt5.QtCore import *
print(QT_VERSION_STR)
- pip加速国内镜像
阿里云 https://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
豆瓣(douban) https://pypi.douban.com/simple/
清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/
2.PyQt5基本UI
2.1 第一个PyQt程序
import sys
from PyQt5.QtWidgets import QApplication, QWidget # 1.导入模块
if __name__ == '__main__':
# 2.创建一个 QApplication 对象,指向QApplication ,接受命令行参数
app = QApplication(sys.argv)
# 3. 创建一个 QWidget对象
w = QWidget()
# 4. 设置窗口标题
w.setWindowTitle("第一个PyQt")
# 5. 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
2.2 argv
import sys
print(sys.argv)
2.3 模块介绍
PyQt中有非常多的功能模块,开发中最常用的功能模块主要有三个:
- QtCore:包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用
- QtGui:包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类
- QtWidgets:包含了一些列创建桌面应用的UI元素
可以参考PyQt官网的所有模块,地址:https://www.riverbankcomputing.com/static/Docs/PyQt5/module_index.html#ref-module-index
C++具体实现的API文档,地址:https://doc.qt.io/qt-5/qtwidgets-module.html
用到什么功能就它相关的api或者别人分享的使用心得,这是学习最快的方式
3.基本UI
窗口内的所有控件,若想在窗口中显示,都需要表示它的父亲是谁,而不能直接使用 show 函数显示
3.1 按钮QPushButton
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt程序")
# 在窗口里面添加控件
btn = QPushButton("按钮")
# 设置按钮的父亲是当前窗口,等于是添加到窗口中显示
btn.setParent(w)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
3.2 文本QLabel
纯文本控件名称为 QLabel
, 位于 PyQt5.QtWidgets
里面
纯文本控件仅仅作为标识显示而已,类似输入内容前的一段标签提示(账号 、密码)
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt")
# # 下面创建一个Label,然后调用方法指定父类
# label = QLabel("账号: ", w)
# # 设置父对象
# label.setParent(w)
# 下面创建一个Label(纯文本),在创建的时候指定了父对象
label = QLabel("账号: ", w)
# 显示位置与大小 : x, y , w, h
label.setGeometry(20, 20, 30, 30)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt")
# # 下面创建一个Label,然后调用方法指定父类
# label = QLabel("账号: ", w)
# 设置父对象
# label.setParent(w)
# 下面创建一个Label(纯文本),在创建的时候指定了父对象
label = QLabel("账号: ", w)
# 显示位置与大小 : x, y , w, h
label.setGeometry(20, 20, 30, 30)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
3.3 输入框
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt")
# 纯文本
label = QLabel("账号", w)
label.setGeometry(20, 20, 30, 20)
# 文本框
edit = QLineEdit(w)
edit.setPlaceholderText("请输入账号")
edit.setGeometry(55, 20, 200, 20)
# 在窗口里面添加控件
btn = QPushButton("注册", w)
# x,y,w,h
btn.setGeometry(50, 80, 70, 30)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
3.4 调整窗口大小
- resize
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt5程序")
# 窗口的大小
w.resize(500,500)
# 纯文本
label = QLabel("账号", w)
# 设置位置x,y,w,h
label.setGeometry(20, 20, 30, 20)
# 文本框
edit = QLineEdit(w)
edit.setPlaceholderText("请输入账号")
edit.setGeometry(55, 20, 200, 20)
# 在窗口里面添加控件
btn = QPushButton("注册", w)
btn.setGeometry(50, 80, 70, 30)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
3.5 调整窗口显示屏幕中间
- move:移动屏幕
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit,QDesktopWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
# 设置窗口标题
w.setWindowTitle("第一个PyQt5程序")
# 窗口的大小
w.resize(500,500)
# 调整到左上角
# w.move(0,0)
# 获取屏幕中心点
center = QDesktopWidget().availableGeometry().center()
print("center:",center)
x = center.x()
y = center.y()
# print(x/2,y/2)
w.move(x//2,y//2)
# 纯文本
print(w.frameSize())
print(w.frameGeometry())
print(w.frameGeometry().getRect())
# 居中显示
old_x,old_y,width,height = w.frameGeometry().getRect()
w.move(x-width//2,y-height//2)
label = QLabel("账号", w)
# 设置位置x,y,w,h
label.setGeometry(20, 20, 30, 20)
# 文本框
edit = QLineEdit(w)
edit.setPlaceholderText("请输入账号")
edit.setGeometry(55, 20, 200, 20)
# 在窗口里面添加控件
btn = QPushButton("注册", w)
btn.setGeometry(50, 80, 70, 30)
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
3.6 设置窗口icon
可下载icon网址
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
# 创建一个QWidget
w = QWidget()
# 设置标题
w.setWindowTitle("看看我图标帅吗")
# 设置图标
w.setWindowIcon(QIcon('test.jpg'))
# 显示QWidget
w.show()
app.exec()
4.布局
在Qt里面布局分为四个大类 :
- QBoxLayout
- QGridLayout
- QFormLayout
- QStackedLayout
4.1 QBoxLayout
直译为:盒子布局
一般使用它的两个子类QHBoxLayout
和 QVBoxLayout
负责水平和垂直布局
4.1.1 垂直布局
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QPushButton, QGroupBox, QMainWindow
from PyQt5.QtCore import Qt
class MyWindow(QWidget):
def __init__(self):
# 切记一定要调用父类的__init__方法,因为它里面有很多对UI空间的初始化操作
super().__init__()
# 设置大小
self.resize(300, 300)
# 设置标题
self.setWindowTitle("垂直布局")
# 垂直布局
layout = QVBoxLayout()
# 作用是在布局器中增加一个伸缩量,里面的参数表示QSpacerItem的个数,默认值为零
# 会将你放在layout中的空间压缩成默认的大小
# 下面的笔试1:1:1:2 : 2
layout.addStretch(1)
# 按钮1
btn1 = QPushButton("按钮1")
# 添加到布局器中
# layout.addWidget(btn1, Qt.AlignmentFlag.AlignTop)
layout.addWidget(btn1)
layout.addStretch(1)
# 按钮2
btn2 = QPushButton("按钮2")
# 添加到布局器
layout.addWidget(btn2)
layout.addStretch(1)
# 按钮3
btn3 = QPushButton("按钮3")
# 添加到布局器
layout.addWidget(btn3)
layout.addStretch(2)
btn4 = QPushButton("按钮4")
# 添加到布局器
layout.addWidget(btn4)
layout.addStretch(2)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
# 创建一个QWidget子类
w = MyWindow()
w.show()
app.exec()
4.1.2 水平布局
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QHBoxLayout, QRadioButton
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# 最外层的垂直布局,包含两部分:爱好和性别
container = QVBoxLayout()
# -----创建第1个组,添加多个组件-----
# hobby 主要是保证他们是一个组。
hobby_box = QGroupBox("爱好")
# v_layout 保证三个爱好是垂直摆放
v_layout = QVBoxLayout()
btn1 = QRadioButton("抽烟")
btn2 = QRadioButton("喝酒")
btn3 = QRadioButton("烫头")
# 添加到v_layout中
v_layout.addWidget(btn1)
v_layout.addWidget(btn2)
v_layout.addWidget(btn3)
# 把v_layout添加到hobby_box中
hobby_box.setLayout(v_layout)
# -----创建第2个组,添加多个组件-----
# 性别组
gender_box = QGroupBox("性别")
# 性别容器
h_layout = QHBoxLayout()
# 性别选项
btn4 = QRadioButton("男")
btn5 = QRadioButton("女")
# 追加到性别容器中
h_layout.addWidget(btn4)
h_layout.addWidget(btn5)
# 添加到 box中
gender_box.setLayout(h_layout)
# 把爱好的内容添加到容器中
container.addWidget(hobby_box)
# 把性别的内容添加到容器中
container.addWidget(gender_box)
# 音乐标签
music_box = QGroupBox("音乐")
m_layout = QHBoxLayout()
btn6 = QRadioButton("古风")
btn7 = QRadioButton("流行")
m_layout.addWidget(btn6)
m_layout.addWidget(btn7)
music_box.setLayout(m_layout)
container.addWidget(music_box)
# 设置窗口显示的内容是最外层容器
self.setLayout(container)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
4.2 QGridLayout
网格布局
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLineEdit, QGridLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle("计算器")
# 准备数据
data = {
0: ["7", "8", "9", "+", "("],
1: ["4", "5", "6", "-", ")"],
2: ["1", "2", "3", "*", "<-"],
3: ["0", ".", "=", "/", "C"]
}
# 整体垂直布局
layout = QVBoxLayout()
# 输入框
edit = QLineEdit()
edit.setPlaceholderText("请输入内容")
# 把输入框添加到容器中
layout.addWidget(edit)
# 网格布局
grid = QGridLayout()
# 循环创建追加进去
for line_number, line_data in data.items():
# 此时line_number是第几行,line_data是当前行的数据
for col_number, number in enumerate(line_data):
# 此时col_number是第几列,number是要显示的符号
btn = QPushButton(number)
# grid.addWidget(btn)
grid.addWidget(btn, line_number, col_number)
# 把网格布局追加到容器中
layout.addLayout(grid)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
4.3 QFormLayout
一般适用于提交数据form表单。比如: 登录,注册类似的场景
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QVBoxLayout, QFormLayout, QLineEdit, QPushButton, QApplication, QWidget
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# 设定当前Widget的宽高(可以拉伸大小)
# self.resize(300, 200)
# 禁止改变宽高(不可以拉伸)
self.setFixedSize(300, 150)
# 外层容器
container = QVBoxLayout()
# 表单容器
form_layout = QFormLayout()
# 创建1个输入框
edit = QLineEdit()
edit.setPlaceholderText("请输入账号")
form_layout.addRow("账号:", edit)
# 创建另外1个输入框
edit2 = QLineEdit()
edit2.setPlaceholderText("请输入密码")
form_layout.addRow("密码:", edit2)
# 将from_layout添加到垂直布局器中
container.addLayout(form_layout)
# 按钮
login_btn = QPushButton("登录")
login_btn.setFixedSize(100, 30)
# 把按钮添加到容器中,并且指定它的对齐方式
container.addWidget(login_btn, alignment=Qt.AlignRight)
# 设置当前Widget的布局器,从而显示这个布局器中的子控件
self.setLayout(container)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
4.4 抽屉布局
提供了多页面切换的布局,一次只能看到一个界面。 抽屉布局
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QStackedLayout, QLabel
class Window1(QWidget):
def __init__(self):
super().__init__()
QLabel("我辈岂是蓬蒿人", self)
self.setStyleSheet("background-color:green;")
class Window2(QWidget):
def __init__(self):
super().__init__()
QLabel("人生得以须尽欢", self)
self.setStyleSheet("background-color:red;")
class MyWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.create_stacked_layout()
self.init_ui()
def create_stacked_layout(self):
# 创建堆叠(抽屉)布局
self.stacked_layout = QStackedLayout()
# 创建单独的Widget
win1 = Window1()
win2 = Window2()
# 将创建的2个Widget添加到抽屉布局器中
self.stacked_layout.addWidget(win1)
self.stacked_layout.addWidget(win2)
def init_ui(self):
# 设置Widget大小以及固定宽高
self.setFixedSize(300, 270)
# 1. 创建整体的布局器
container = QVBoxLayout()
# 2. 创建1个要显示具体内容的子Widget
widget = QWidget()
widget.setLayout(self.stacked_layout)
widget.setStyleSheet("background-color:grey;")
# 3. 创建2个按钮,用来点击进行切换抽屉布局器中的Widget
btn_press1 = QPushButton("抽屉1")
btn_press2 = QPushButton("抽屉2")
# 给按钮添加事件(即点击后要调用的函数)
btn_press1.clicked.connect(self.btn_press1_clicked)
btn_press2.clicked.connect(self.btn_press2_clicked)
# 4. 将需要显示的空间添加到布局器中
container.addWidget(widget)
container.addWidget(btn_press1)
container.addWidget(btn_press2)
# 5. 设置当前要显示的Widget,从而能够显示这个布局器中的控件
self.setLayout(container)
def btn_press1_clicked(self):
# 设置抽屉布局器的当前索引值,即可切换显示哪个Widget
self.stacked_layout.setCurrentIndex(0)
def btn_press2_clicked(self):
# 设置抽屉布局器的当前索引值,即可切换显示哪个Widget
self.stacked_layout.setCurrentIndex(1)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyWindow()
win.show()
app.exec()
5. 窗口
5.1 分类
在Qt中,生成窗口有三种方式: QWidget
| QMainWindow
| QDialog
- QWidget
控件和窗口的父类 ,自由度高(什么都东西都没有),没有划分菜单、工具栏、状态栏、主窗口 等区域
- QMainWindow
是 QWidget
的子类,包含菜单栏,工具栏,状态栏,标题栏等,中间部分则为主窗口区域
- QDialog
对话框窗口的基类
5.2 QWidget
import sys
from PyQt5.QtWidgets import QWidget, QLabel , QApplication
class mywnd(QWidget):
def __init__(self):
super(mywnd, self).__init__()
self.initUI()
def initUI(self):
label = QLabel("这是文字~~" )
label.setStyleSheet("font-size:30px;color:red")
label.setParent(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = mywnd()
#设置窗口标题
w.setWindowTitle("qwidget")
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
5.2 QMainWindow
import sys
from PyQt5.QtWidgets import QMainWindow, QLabel, QApplication
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
label = QLabel("这是文字~~")
label.setStyleSheet("font-size:30px;color:red")
# 调用父类中的menuBar,从而对菜单栏进行操作
menu = self.menuBar()
# 如果是Mac的话,菜单栏不会在Window中显示而是屏幕顶部系统菜单栏位置
# 下面这一行代码使得Mac也按照Windows的那种方式在Window中显示Menu
menu.setNativeMenuBar(False)
file_menu = menu.addMenu("文件")
file_menu.addAction("新建")
file_menu.addAction("打开")
file_menu.addAction("保存")
edit_menu = menu.addMenu("编辑")
edit_menu.addAction("复制")
edit_menu.addAction("粘贴")
edit_menu.addAction("剪切")
# 设置中心内容显示
self.setCentralWidget(label)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
# 设置窗口标题
w.setWindowTitle("我是窗口标题....")
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
5.3 QDialog
import sys
from PyQt5.QtWidgets import QDialog, QPushButton, QApplication
class MyDialog(QDialog):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
ok_btn = QPushButton("确定", self)
ok_btn.setGeometry(50, 50, 100, 30)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyDialog()
# 设置窗口标题
w.setWindowTitle("对话框")
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec()
6. 信号与槽
6.1 信号与槽介绍
一、说明
信号和槽是 Qt的核心内容
- 信号(signal)
其实就是事件(按钮点击 、内容发生改变 、窗口的关闭事件) 或者是 状态 (check选中了, togglebutton 切换。)
当程序触发了某种状态或者发生了某种事件(比如:按钮被点击了, 内容改变等等),那么即可发射出来一个信号。
-
槽( slot)
若想捕获这个信号,然后执行相应的逻辑代码,那么就需要使用到槽 , 槽实际上是一个函数, 当信号发射出来后,会执行与之绑定的槽函数 -
将信号与槽链接
为了能够实现,当点击某个按钮时执行某个逻辑,需要把具体的信号和具体的槽函数绑定到一起.
操作大体流程如下
对象.信号.connect(槽函数)
当出现了某一种信号(某一种事件)的时候,我们需要执行一段代码(用函数来包装这份代码。)
解决办法
信号和槽
6.2 案例
功能:接收信号
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# 更改当前Widge的宽高
self.resize(500, 300)
# 创建一个按钮
btn = QPushButton("点我点我", self)
# 设置窗口位置、宽高
btn.setGeometry(200, 200, 100, 30)
# 将按钮被点击时触发的信号与我们定义的函数(方法)进行绑定
# 注意:这里没有(),即写函数的名字,而不是名字()
btn.clicked.connect(self.click_my_btn)
def click_my_btn(self, arg):
# 槽函数,点击按钮则调用该函数
# 这里的参数正好是信号发出,传递的参数
print("点击按钮啦~", arg)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
6.3 自定义信号
除了接收Qt自带的信号之外,我们也可以自行定义信号,在合适的时机,自行发射信号
自定义信号需要使用到 pyqtSignal
来声明信号 ,并且需要在类中的函数之外声明
如果会自定义信号,那么信号和槽基本上也就掌握了。否则永远只会接收别人发射出的信号
import sys
import time
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class MyWindow(QWidget):
# 声明一个信号 只能放在函数的外面
my_signal = pyqtSignal(str)
def __init__(self):
super().__init__()
self.init_ui()
self.msg_history = list() # 用来存放消息
def init_ui(self):
self.resize(500, 200)
# 创建一个整体布局器
container = QVBoxLayout()
# 用来显示检测到漏洞的信息
self.msg = QLabel("")
self.msg.resize(440, 15)
# print(self.msg.frameSize())
self.msg.setWordWrap(True) # 自动换行
self.msg.setAlignment(Qt.AlignCenter) # 靠上
self.msg.setStyleSheet("background-color: yellow; color: red;")
# 创建一个滚动对象
scroll = QScrollArea()
scroll.setWidget(self.msg)
# 创建垂直布局器,用来添加自动滚动条
v_layout = QVBoxLayout()
v_layout.addWidget(scroll)
# 创建水平布局器
h_layout = QHBoxLayout()
btn = QPushButton("开始检测", self)
# 绑定按钮的点击,点击按钮则开始检测
btn.clicked.connect(self.check)
h_layout.addStretch(1) # 伸缩器
h_layout.addWidget(btn)
h_layout.addStretch(1)
# 操作将要显示的控件以及子布局器添加到container
container.addLayout(v_layout)
container.addLayout(h_layout)
# 设置布局器
self.setLayout(container)
# 绑定信号和槽
self.my_signal.connect(self.my_slot)
def my_slot(self, msg):
# 更新内容
print(msg)
self.msg_history.append(msg)
self.msg.setText("<br>".join(self.msg_history))
self.msg.resize(440, self.msg.frameSize().height() + 15)
self.msg.repaint() # 更新内容,如果不更新可能没有显示新内容
def check(self):
for i, ip in enumerate(["192.168.1.%d" % x for x in range(1, 255)]):
msg = "模拟,正在检查 %s 上的漏洞...." % ip
# print(msg)
if i % 5 == 3:
# 表示发射信号 对象.信号.发射(参数)
self.my_signal.emit(msg + "【发现漏洞】")
time.sleep(0.01)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec()
7.Qt Designer
7.1 介绍
纯靠代码来编写界面,效率属实是有点底,今天我们用另外一个辅助设计图形化的软件 QT Designer
7.2 下载
Mac版本:[http://download.codetutor.top/software/Mac/Qt%20Designer.dmg](http://download.codetutor.top/software/Mac/Qt Designer.dmg)
Windows版本:[http://download.codetutor.top/software/win/Qt%20Designer%20Setup.exe](http://download.codetutor.top/software/win/Qt Designer Setup.exe)
7.3 安装&运行
安装过程很简单,按照正常软件安装即可,安装后的图片如下图:
但Mac平台用户要注意,运行时会出现如下图问题:
解决办法:在“应用程序”文件夹,按住control
键然后运行。只需要这种方式运行第一次即可,以后运行就像普通软件一样打开
7.4 使用QT Designer
Mac运行之后的效果如下:
7.5 使用流程
1.创建一个基于QWidget的界面
2.此时会创建一个新的窗口,如下效果
3.拖动想要的控件
4.选中控件,看属性
5.修改属性
6.如果没有看到preperty等窗口怎么办?看下图
7.信号与槽(没有没有看到Singal/Slot Editor请按照上一步操作进行显示)
8.预览效果
9.保存
10.python代码使用test.ui
文件
若要加载ui文件,则需要导入 uic
模块 , 它位于PyQt5
中
"""
动态加载ui文件
"""
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = uic.loadUi("./test.ui")
# 展示窗口
ui.show()
app.exec()
参考资料
www.itprojects.cn