【PyQt学习篇 · ②】:QObject - 神奇的对象管理工具

2023-10-29 04:15

本文主要是介绍【PyQt学习篇 · ②】:QObject - 神奇的对象管理工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • QObject介绍
  • Object的继承结构测试
  • QObject对象名称和属性
    • QObject对象名称和属性的操作
    • 应用场景
  • QObject父子对象
    • QObject父子对象的操作
  • QObject的信号与槽
    • QObject的信号与槽的操作

QObject介绍

在PyQt中,QObject是Qt框架的核心对象之一。QObject是一个基类,它提供了对象之间的信号和槽机制、父子对象关系管理、对象属性以及事件处理等功能。

以下是QObject类的一些常用特性和功能:

  1. 信号和槽机制:QObject支持信号和槽机制,用于实现对象之间的通信。通过定义信号和槽,可以在事件发生时触发、连接和处理功能。信号可以在特定条件下被发射,而槽则是处理信号的函数。

  2. 父子对象关系:QObject支持父子对象关系的管理。可以使用setParent()方法将一个QObject对象设置为另一个QObject对象的父对象。当父对象被销毁时,它会负责销毁其所有的子对象。

  3. 对象属性:QObject支持动态属性机制,可以通过setProperty()方法设置对象的属性值,并可以通过property()方法获取属性值。属性可以用于存储对象的状态或其他自定义信息。

  4. 事件处理:QObject提供了处理事件的基本机制。可以通过重写event()eventFilter()方法来处理对象接收到的事件。事件可以是鼠标事件、键盘事件或其他自定义事件。

  5. 对象生命周期管理:QObject对象在创建后可以自动管理其生命周期。在Python中,当一个QObject对象没有引用时,它会被Python的垃圾回收器销毁。同时,QObject的父子关系机制也可以在父对象销毁时自动销毁子对象。

QObject是PyQt中其他重要对象(如QWidget、QThread等)的基类,它为它们提供了共享的核心功能和特性。

下面,将从以下基本程序展开演示QObject的具体使用方法:

class Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle("QLabel的学习")self.resize(500, 500)self.setup_ui()# 调用以下文章自定义的函数def setup_ui(self):passif __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())

注意:

  • 在以上代码中,self代表当前实例化的Window对象。在Python中,通过使用self关键字,可以在类的方法中引用对象自身。

  • 在构造函数中的super().__init__()调用中,self被用于传递当前对象自身给父类的构造函数,确保父类的初始化操作能够正确地处理当前对象。

Object的继承结构测试

如以下代码所示,在Window()类中自定义一个QObject_Inheritance_Structure_Testing(self)方法,在该方法中,通过调用QObject.mro()方法,可以获取到QObject类的方法解析顺序。方法解析顺序决定了当一个方法被调用时,解释器在哪个类中找到该方法的定义。通过打印每个继承类,可以查看继承结构中各个类的排列顺序。

    # QObject继承结构测试def QObject_Inheritance_Structure_Testing(self):mros  = QObject.mro()for mro in mros:print(mro)

运行结果:

在这里插入图片描述
这些打印结果表示了QObject类的继承关系。QObject类继承自sip.wrapper类,sip.wrapper类又继承自sip.simplewrapper类,最后都继承自object类。继承结构定义了这些类之间的层次关系,使得QObject类可以具有基类和扩展类提供的功能和属性。

QObject对象名称和属性

在进行QObject对象的名称和属性操作时,可以使用以下 API:

  1. setObjectName(name): 设置对象的名称,可以用于在后续代码中查找和识别具体的对象。一般这个名称是唯一的,当做对象的ID来使用。
  2. objectName(): 获取对象的名称。
  3. setProperty(name, value): 设置对象的属性,可以用于存储和传递自定义的数据。
  4. property(name): 获取对象的属性值。
  5. dynamicPropertyNames(): 获取对象所有动态属性的名称列表。

QObject对象名称和属性的操作

以下将对演示如何使用这些API:

	# QObject对象名称和属性def Operation_of_QObject_object_names_and_attributes(self):# QObject的对象操作obj = QObject()obj.setObjectName("notice")     # 设置对象的名称print(obj.objectName())     # 打印对象的名称# QObject的属性操作obj.setProperty("notice_level", "error")    # 设置了notice_level属性,其值为error,同等于notice_level="error"obj.setProperty("notice_level2", "warning")print(obj.property("notice_level2"))     # 打印notice_level2属性的值print(obj.dynamicPropertyNames())   # 获取对象obj的所有动态属性名称列表并打印

运行结果:

在这里插入图片描述

应用场景

在本篇文章中,QObject对象名称和属性的主要演示的应用场景:用于qss的ID选择器,属性选择器,方便统一设置样式。

设置qss样式方法一:使用setStyleSheet()方法。

        label = QLabel(self)label.setText("Hello world")# 设置qss样式label.setStyleSheet("font-size: 20px; color: red;")

运行结果:

在这里插入图片描述
通过设置qss样式,将字体的大小变为20px,颜色变为红色。

设置qss样式方法二

  • 创建一个QObject.qss文件,在文件内写入对应的qss样式
QLabel#notice {font-size: 20px;color: red;
}QLabel#notice[notice_level="warning"] {font-size: 30px;color: yellow;
}

在以上qss样式中,notice为对象的名称,notice_levelwarning为对象的属性及其值。

  • 编写使用该样式的程序
        with open("QObject.qss", "r") as f:qApp.setStyleSheet(f.read())    # 读取整个字符串并赋值给app全局变量label = QLabel(self)label.setText("Hellow world")label.setObjectName("notice")  # 设置对象名称,即IDlabel2 = QLabel(self)label2.move(100, 100)label2.setText("PyQt5")label2.setObjectName("notice")  # 设置对象名称,即IDlabel2.setProperty('notice_level', 'warning')   # 设置对象的属性及其值btn = QPushButton(self)btn.setText("我是按钮")btn.move(50, 50)

在以上代码中,打开名为QObject.qss的样式表文件,读取其中的内容,并将其应用于应用程序全局变量qApp。因为样式表文件中只设置了QLabel的样式,所以只会匹配QLabel对象,并根据对象的名称和属性匹配其样式。

运行结果:
在这里插入图片描述

QObject父子对象

在PyQt中,可以使用以下API来操作QObject的父子对象:

  1. setParent(parent): 将当前对象设置为指定父对象的子对象。当父对象被销毁时,所有的子对象也会被自动销毁。
  2. parent(): 返回当前对象的父对象。
  3. children(): 返回当前对象的直接子对象列表。
  4. findChild( type, objectName): 在当前对象的子对象中查找指定名称和类型的对象。如果找到,则返回该对象;否则返回 None。
  5. findChildren(type): 在当前对象的子对象中查找指定类型的所有对象并返回一个列表。

其中,findChildfindChildren方法是一些方便的查找子对象的API。findChild方法需要传入待查找对象的名称和类型作为参数;而findChildren方法只需要传入待查找对象的类型即可。这两个方法都只会查找当前对象的直接子对象,不会递归查找其子孙对象。

QObject父子对象的操作

尝试构造以下父子关系:

在这里插入图片描述

    # QObject父子对象的操作def QObject_Parent_Child_Object(self):# 创建五个QObject对象obj0 = QObject()obj1 = QObject()obj2 = QObject()obj3 = QObject()obj4 = QObject()obj5 = QObject()print('obj0', obj0)     # 打印obj0对象的地址print('obj1', obj1)print('obj2', obj2)print('obj3', obj3)print('obj4', obj4)print('obj5', obj5, '\n')obj1.setParent(obj0)    # 设置obj1的父对象为obj0obj2.setParent(obj0)    # 设置obj2的父对象为obj0print('obj0 children: ', obj0.children(), '\n')   # 查看obj0的直接子对象列表print('未修改父对象前,父对象:', obj2.parent())      # 未修改父对象前obj2.setParent(obj1)print('修改父对象后,父对象:', obj2.parent(), '\n')      # 修改父对象后print('obj0 children: ', obj0.children())  # 修改obj2的父对象后,查看obj0的直接子对象列表obj3.setParent(obj1)    # 设置obj3的父对象为obj1obj4.setParent(obj2)    # 设置obj4的父对象为obj2obj5.setParent(obj2)    # 设置obj5的父对象为obj2

在以上代码中,设置了两次obj2的父对象,第一次设置的父对象为obj0,第二次设置的父对象为obj1。

运行结果:

在这里插入图片描述
从运行结果可看出,一个对象,它的父对象只能有一个,且以最后设置的父对象为主。

再观察以下代码,学习findChild(objectName, type)findChildren(type)的使用:

    # QObject父子对象的操作def QObject_Parent_Child_Object(self):# 创建五个QObject对象obj0 = QObject()obj1 = QObject()obj2 = QObject()obj3 = QObject()obj4 = QObject()obj5 = QObject()print('obj0', obj0)     # 打印obj0对象的地址print('obj1', obj1)print('obj2', obj2)print('obj3', obj3)print('obj4', obj4)print('obj5', obj5, '\n')obj1.setParent(obj0)    # 设置obj1的父对象为obj0obj2.setParent(obj0)    # 设置obj2的父对象为obj0obj2.setObjectName("2")     # 设置obj2对象的名称为2obj3.setParent(obj1)    # 设置obj3的父对象为obj1obj4.setParent(obj2)    # 设置obj4的父对象为obj2obj5.setParent(obj2)    # 设置obj5的父对象为obj2print(obj0.findChild(QObject))  # 返回第一个子对象,即返回obj1的地址print(obj0.findChild(QObject, "2"))     # 获取obj0的QObject类型且对象名称为2的子对象print(obj0.findChild(QObject, "3"))     # 获取obj0的QObject类型且对象名称为3的子对象,没有时返回Noneprint(obj0.findChildren(QObject))   # 获取obj0的所有QObject类型的子对象

运行结果:

在这里插入图片描述

QObject的信号与槽

在PyQt中,信号与槽(Signals and Slots)是一种用于实现对象间通信的机制。信号是由发送者发出的消息,而槽是接收信号并对其做出响应的方法。以下是PyQt中常用的信号与槽相关的API:

  1. 信号(Signal)相关的API:

    • pyqtSignal(): 创建一个自定义信号。
    • emit(): 发出信号,即调用信号对象的emit()方法。
  2. 槽(Slot)相关的API:

    • @pyqtSlot(): 将一个方法声明为槽函数。
    • connect(): 连接一个信号与一个槽函数。
    • disconnect(): 断开一个信号与一个槽函数的连接。
    • sender(): 返回发出信号的对象。
    • blockSignals(bool): 暂时阻塞或取消阻塞信号。
    • receivers(sign):返回连接到信号的接收器数量
  3. 信号与槽的连接相关的API:

    • QMetaObject.connectSlotsByName(self, obj): 通过对象的命名约定自动连接信号与槽函数。

QObject的信号与槽的操作

# QObject的信号与槽
def Signal_and_slot_of_QObject(self):self.obj = QObject()def destroy_slot(obj):print('对象被释放了', obj)def obj_name_slot(name):print('对象名称发生了改变', name)self.obj.objectNameChanged.connect(obj_name_slot)   # 建立与obj_name_slot槽函数的连接self.obj.destroyed.connect(destroy_slot)   # 建立与destroy_slot槽函数的连接self.obj.setObjectName('xxx')self.obj.objectNameChanged.disconnect()     # 取消连接self.obj.setObjectName('yyy')self.obj.objectNameChanged.connect(obj_name_slot)   # 再次建立与槽函数的连接self.obj.setObjectName('xxyy')self.obj.blockSignals(True)     # 临时阻断连接self.obj.setObjectName('111')self.obj.blockSignals(False)    # 重新连接self.obj.setObjectName('222')print(self.obj.receivers(self.obj.objectNameChanged))   # 获取objectNameChanged信号绑定的槽函数数量del self.obj

运行结果:

在这里插入图片描述

这篇关于【PyQt学习篇 · ②】:QObject - 神奇的对象管理工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/298186

相关文章

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.