当前位置:   article > 正文

GUI编程--PyQt5--QObject_pyqt5 类定义

pyqt5 类定义

对象的名称和属性

在这里插入图片描述

# 实例化对象
obj = QObject()

# 设置名称, 可以重复
obj.setObjectName("名")
# 设置属性
obj.setProperty("name", "jack")
obj.property("name") # 获取属性值

# 获取所有的动态属性
obj.dynamicPropertyNames()

# 设置样式使用qss, 类似css样式表
label = QLabel(window)
label.setText("富文本")
label.setStyleSheet("color:red; font-size:24px;")

# 也可以创建.qss 文件,设置样式
# 控件选择器
QLabel {
	color: red;
	font-size: 24px;
}

// 控件选择器  + id选择器
QPushButton#pp{
	color: blue;
}
//id选择器  + 属性
QPushButton#pp[name="jack"]{
	key: value;  /*类似css*/
}

//也可以直接通过id选择器实现
#pp[name=laufing]{
    color: red;
    background: gray;
    font-weight: bold;
    font-style: italic;
    padding: 2px;
    margin: 20px;
    width: 50px;
    height: 100px;
    border-style: solid;
    border-width: 2px;
    border-color: yellow;
    text-align: right;
}
# 使用样式文件
from PyQt5.Qt import qApp
with open("style.qss", "r") as f:
	qApp.setStyleSheet(f.read())
  • 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
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

在这里插入图片描述
其他参考

QObject对象的父子关系

from PyQt5.QtCore import QObject

obj1 = QObject()
obj2 = QObject()

# 设置父对象
obj2.setParent(obj1)
# 查看父对象
obj2.parent()

# 查看直接子对象
obj1.children()
# 查找一个子对象
obj1.findChild(类型, 对象名称, 查找方式)
obj1.findChild(QObject, 'laufing', Qt.FindChildrenRecursively)
obj1.findChild(QObject, 'laufing', Qt.FindDirectChildrenOnly)
obj1.findChildren()  # 查找多个子对象
# 导入
from PyQt5.QtCore import Qt
Qt.FindChildOption.FindChildrenRecursively
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

Qt的内存管理

1. 所有的对象都直接或者间接的继承QObject,形参QObject继承树;
2. 当实例化一个QObject对象时,若指定父对象,则该QObject对象则会放入父对象的children列表中
3. 父对象销毁时,其所有的子对象也一起销毁,避免内存泄漏。

 # 在一个函数中测试如下:
 obj1 = QObject()
 obj2 = QObject()

 obj2.setParent(obj1)
 # 删除信号  连接槽函数
 obj1.destroyed.connect(lambda : print("obj1被销毁"))
 obj2.destroyed.connect(lambda :print("obj2被销毁"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

反映到控件:

  1. 当一个控件设置了父控件,那么就被受父控件的管理(大小、生命周期),父控件删除,子控件也被删除
  2. 案例,关闭一个对话框,则删除其内部的所有的子控件。

案例

  1. 创建一个空白窗口,添加多个QLabel、QPushButton等控件
  2. 所有的QLabel都设置cyan背景色
  3. 在添加一个QLabel 控件 也是具有相同的背景色
# __author__ = "laufing"

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QLabel, QPushButton
from PyQt5.QtGui import QIcon, QPixmap
import sys

app = QApplication(sys.argv)

w1 = QWidget()
w1.setWindowTitle("laufing")

icon = QIcon()
icon.addPixmap(QPixmap("./imgs/dog.jpg"), QIcon.Normal, QIcon.Off)
w1.setWindowIcon(icon)
w1.resize(400, 500)
w1.move(300, 300)

label1 = QLabel(w1)
label1.setText("label1")
label1.resize(30, 20)
label1.move(0,20)

label2 = QLabel(w1)
label2.setText("label2")
label2.resize(30, 20)
label2.move(35, 20)

btn = QPushButton(w1)
btn.setText("btn1")
btn.resize(30, 20)
btn.move(70, 20)

# 设置label颜色
for i in w1.findChildren(QLabel):
    i.setStyleSheet("background-color:cyan")

w1.show()

exit_code = app.exec_()


sys.exit(exit_code)
  • 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
  • 40
  • 41
  • 42
  • 43
  • 44

 
 

QObject 信号的操作

信号与槽机制, Qt中的核心机制,用户对象之间通信。
当一个控件的状态发生变化时,会发出信号,然后提前连接的槽函数,执行相应的操作。
继承QWidget的控件,都支持信号与槽机制

在这里插入图片描述
 
 
信号种类:
内置
QPushButton().pressed, 按下时
QPushButton().clicked 点击时

自定义
pyqtSignal()

槽函数种类
内置 & 自定义函数

建立连接
object.信号.connect(槽函数)
信号与槽 是多对多关系,一个信号可以连接多个槽函数,一个槽函数也可以监听多个信号。
信号也可以连接另一个信号

具体使用:

obj1 = QObject()
# 对象被销毁时,发出destroyed信号,绑定槽函数
obj1.destroyed.connect(myFunc)  # myFunc定义时,可以接收参数obj, 就是触发信号的对象。

obj1.objectNameChanged.connect(func1)  # 槽函数会接收 改后的名字

# 取消信号与槽函数的连接,信号依旧触发,但没有函数的执行
obj1.objectNameChanged.disconnect()

# 临时取消 信号与槽的连接
obj1.blockSignals(True)
obj1.blockSignals(False) # 恢复

# 查看信号是否阻塞
obj1.signalsBlocked()  # 返回True or False
# 信号连接的槽函数 数量
obj1.receivers(obj1.objectNameChanged)  # 必须传入信号

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

案例
实现窗口中放置一个按钮,点击时,每次更改窗口的标题,如
点击一次, 变为“laufing 1”
点击二次,变为“laufing2”

# 核心代码
#
click_times = 0


def func1(p):
    # 声明是全局变量,默认赋值的变量为局部变量
    global click_times
    click_times += 1
    # p 为 False  ?
    print("点击按钮,更改窗口的名称:", p, type(p))

    # 设置窗口标题(顶级控件)
    print(w1)
    w1.setWindowTitle("laufing")


def func2(p):
    print("窗口名字改变:", p)
    # 声明是全局变量
    global click_times

    # 修改窗口标题
    w1.blockSignals(True)  # 临时阻塞信号
    w1.setWindowTitle("laufing " + str(click_times)) # 设置标题
    w1.blockSignals(False) # 取消信号阻塞


# 信号与槽 连接
w1.windowTitleChanged.connect(func2)
w1.setWindowTitle("6666")

btn.clicked.connect(func1)
  • 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

QObject 类型判定

# 判定对象是否是某个类型
obj.isWidgetType()  # 对象是否 为控件类型
obj.inherits("QWidget")   # 返回bool
obj.inherits("QLabel")
  • 1
  • 2
  • 3
  • 4

QObject 对象的删除

deleteLater() 稍后删除一个对象,并与父对象解出关系;
给消息循环发送一个事件,下次循环时再删除;
在本次循环,还可以继续完成相关操作。

# 删除一个对象
obj.deleteLater()
  • 1
  • 2

事件机制

用户的操作会产生消息,放入消息队列中:
操作系统的消息队列, 如键盘事件、鼠标事件
应用程序的消息队列,如控件的点击事件

消息循环不断扫描消息队列,将消息封装为QEvent对象,交给QApplicationnotify方法,进行二次分发,分发给事件源对象的event方法,然后在根据事件的类型分发给事件源对象的事件函数。
在这里插入图片描述
在这里插入图片描述

# 定义自己的应用类,并实例化
class App(QApplication):
    def notify(self, receiver, event):
        # receiver  事件的接收对象(事件源), 如按钮
        # event QEvent对象

        # 过滤事件
        if receiver.inherits("QPushButton") and event.type() == QEvent.MouseButtonPress:
            print("事件:", receiver, event)

        return super().notify(receiver, event)


# 定义一个按钮类并实例化,点击触发事件
class MyBtn(QPushButton): # QPushButton的源码方法 都是pass?
    def event(self, event):
        # 接收事件,并分发给对应的事件函数
        if event.type() == QEvent.MouseButtonPress:
            print("event函数接收事件", event)

        # 父类的event函数分发
        return super(MyBtn, self).event(event)

    # 事件函数
    def mousePressEvent(self, *args, **kwargs):
        # 这里会发出pressed信号,便于连接 槽函数

        print("事件函数执行中....")

        return super().mousePressEvent(*args, **kwargs)

    def mouseReleaseEvent(self, e):
        return super().mouseReleaseEvent(e)

    def mouseDoubleClickEvent(self, e):
        
        print("双击....", e)
        return super(MyBtn, self).mouseDoubleClickEvent(e)

	# 单击是?
  • 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
  • 40

信号与槽 是对事件的封装
为了对python文件进行加密,会把python模块编译成.pyd文件,供其他人调用。拿到一个.pyd文件,在没有文档说明的情况下,可以试试查看模块内的一些函数和类的用法 ,pyd一般使用c/c++ 编写。
 
 

QObject的定时器

在这里插入图片描述

from PyQt5.QtCore import Qt
# Qt.PreciseTimer 精确毫秒
# Qt.CoarseTimer  5%误差
# 定义自己的类
class MyObject(QObject)
	def timerEvent(self, *args, **kwargs):
		print("定时的操作...")
		

# 实例化
obj = MyObject()
# 开启定时器, 毫秒  控件对象直接调用
timer_id = obj.startTimer(1000, 类型)
# 类型 Qt.PreciseTimer 精确到毫秒

# 取消定时器
obj.killTimer(timer_id)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

案例:使用QLabel实现一个倒计时效果
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/816747
推荐阅读
相关标签
  

闽ICP备14008679号