【PyQt5】 1.PyQt5入门学习

一、基本思路结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.导入需要的包和模块
from PyQt5.Qt import * # 主要包含了常用的包和模块
import sys # 通过sys.argv可以获取参数

# 2.创建一个应用程序对象
app = QApplication(sys.argv)
app.arguments() # 获取参数
qApp.arguments() # 全局 qApp获取参数

# 3.控件的操作
# 创建控件,设置样式,信号的处理

# 4.应用程序的执行,进行到 消息循环(无限循环),检测整个程序的用户操作交互
app.exec_()
二、第一个PyQt5程序:hello world
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)

window = QWidget()
window.setWindowTitle("微博搜索助手")
window.resize(500,500)
window.move(400,200)

label = QLabel(window)
label.setText("hello world")
label.move(200,200)

window.show()
sys.exit(app.exec_())
封装成面向对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from PyQt5.Qt import *


class Window(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("学习入门")
self.resize(500,500)
self.setup_ui()

def setup_ui(self):
pass

if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
设置控件样式:
1
2
3
4
5
6
7
8
9
10
11
def setup_ui(self):
# 加载外部样式qss
with open("QLabel.qss",'r') as f:
qApp.setStyleSheet(f.read())

label = QLabel(self)
label.setObjectName("labelStyle")
label.setProperty("notice_level","warning")
label.setText("文本设置样式")
# 单独设置样式,优先级高于外部加载样式
# label.setStyleSheet("font-size:20px;color:red;")

外部样式文件QLabel.qss:

1
2
3
4
5
6
7
8
QLabel#labelStyle {    
font-size:20;
color:yellow;
}
QLabel#labelStyle[notice_level="warning"] {
font-size:40px;
color:red;
}
设置控件的父子关系:
1
2
3
4
5
6
7
8
obj1 = QObject()
obj2 = QObject()
obj1.setParent(obj2) # 设置obj2为obj1的父对象 一个对象的父对象只有一个,以后设置的为父对象
obj1.parent() # 查看obj1的父对象
obj2.children() # 查看obj2的所有的直接子对象
# 参数1:查找的对象类型;参数2:查找的对象名称;参数3:默认是递归查找#(Qt.FindDirectChildrenOnly- 仅查找直接子对象; Qt.FindChildrenRecursively- 递归查找 默认选项)
obj1.findChild(参数1,参数2,参数3)
obj1.findChildren(参数1,参数2,参数3) # 查找所有子对象
内存管理机制:

所有的对象都是直接或者间接的继承QObject

QObject在一个对象树中组织,当创建一个QObject时,如果使用了其他对象作为其父对象,那么他就会添加到父对象的children列表中

当父对象被销毁时,这么QObject对象就会被销毁,其所有子对象同时也会被销毁

子控件和父控件的关系:显示受父控件约束,父控件销毁子控件也会销毁

如果两个控件都没有父控件,那么都会当做单独的顶级控件显示;

只有顶级控件才能设置标题栏等属性信息;

信号与槽机制:

基本概念:

信号(Signal)和槽(slot)是Qt中的核心机制,主要用于对象之间进行通讯

信号:当一个控件的状态发生改变时,向外界发出的信息

槽:一个执行某些操作的函数或方法

所有继承自QWidget的控件都支持信号与槽机制

信号:

控件内置的一些 QPushButton().pressed/clicked

也可以自定义信号:

槽:

不同控件内置的槽函数

自定义的函数方法

连接方式:

object.信号.connect(槽函数)

特性:

一个信号可以连接多个槽函数

一个信号也可以连接多个槽函数

信号的参数可以使任何python类型

一个槽可以监听多个信号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 信号一 演示
obj = QObject()
obj.destroyed.connect(lambda :print("对象已被销毁"))
# ouput:
# 对象已被销毁

# 信号二 演示
def change(name):
print("名称发生改变",name)
obj.objectNameChanged.connect(change)
obj.setObjectName("名称修改")
# ouput:
# 名称发生改变 名称修改

# 断开信号连接
def change(name):
print("名称发生改变",name)
obj.objectNameChanged.connect(change)
obj.setObjectName("名称修改1")
obj.objectNameChanged.disconnect()
obj.setObjectName("名称修改2")
# ouput:
# 名称发生改变 名称修改1

# 临时断开信号连接和恢复信号连接
obj = QObject()
def change(name):
print("名称发生改变",name)
obj.objectNameChanged.connect(change)
obj.setObjectName("名称修改1")
obj.blockSignals(True) # 临时阻断信号连接
obj.setObjectName("名称修改2")
obj.blockSignals(False) # 恢复信号连接
obj.setObjectName("名称修改3")
obj.SignalsBlocked() # 查看连接状态(暂停为True,未暂停未False)
obj.obj.receivers(obj.objectNameChanged) # 输出当前连接对应槽的数量:1
# ouput:
# 名称发生改变 名称修改1
# 名称发生改变 名称修改3
QObject 类型判定
1
2
3
4
5
6
7
8
9
10
11
12
13
obj = QObject()
w = QWidget()
btn = QPushButton()
label = QLabel()
objs = [obj,w,btn,label]
for o in objs:
print(o.isWidgetType()) # 是否是控件类型
# print(o.inherits('QWidget'))# 是否是控件类型
# output:
# False
# True
# True
# True
对象删除 obj.deleteLater():
  1. 删除一个对象时,也会接触它与父对象之间的关系
  2. 并没有将对象立即销毁,而是向主消息循环发送了一个event,下次主循环循环收到这个event之后才会销毁对象
  3. 这样做额好处是可以在这些延迟删除的时间内完成一些操作,坏处就是内存释放会不及时

应用场景:想要移除某个对象时候使用

定时器
1
2
3
4
5
6
7
class MyObject(QObject):
def timerEvent(self,evt):
print(evt,"1")

obj = MyObject()
timer_id = obj.startTimer(1000) # 开启定时器
obj.killTimer(timer_id) # 删除定时器