PYQT5学习笔记05——QObject父子对象API以及案例

一、父子对象API

  我们在这里简单演示一下父子对象API的具体用法以及代码实现,父子对象API有五个,分别是setParent、parent、children、findChild、findChildren,接下来对每一个API都具体演示一下。

1、setParent(parent)和parent()

  setParent方法的作用就是给一个QObject对象设置一个父对象,并且每个对象的父对象只能设置一个。parent的作用就是获取某个对象的父对象,代码如下:

obj1 = QObject()
obj2 = QObject()
print("obj1", obj1)
print("obj2", obj2)
obj1.setParent(obj2)  # 设置obj1的父对象为obj2
print(obj1.parent())

  效果如下,因为输出的是引用,所以我们只能先打印obj1obj2才能知道谁是谁的父对象:
在这里插入图片描述

  这里提醒一下,QLabel对象不能设置QObject对象为自己的父对象,一个可见控件和一个不可见控件是不能相互设置父子关系的!!!

2、children()

  children的作用是获取某个对象的所有直接子对象,我们可以先构造一个父子关系图,关系图如下:
在这里插入图片描述

  构造代码如下:

        obj0 = QObject()
        obj1 = QObject()
        obj2 = QObject()
        obj3 = QObject()
        obj4 = QObject()
        obj5 = QObject()
        #
        print("obj0", obj0)
        print("obj1", obj1)
        print("obj2", obj2)
        print("obj3", obj3)
        print("obj4", obj4)
        print("obj5", obj5)
        #
        obj1.setParent(obj0)
        obj2.setParent(obj0)


        obj3.setParent(obj1)
        obj4.setParent(obj2)
        obj5.setParent(obj2)

  我们可以尝试输出obj4的父亲和obj0的孩子,代码如下:

		print("obj4-parent", obj4.parent())
        print("obj0-child", obj0.children())  # 获取obj0的直接子对象,只有一级

  结果如下:
在这里插入图片描述

  很明显的看出,只输出了obj0的两个直接子对象。

3、findChild(参数1,参数2,参数3),findChildren(参数1,参数2,参数3)

  findChild函数的意思是,根据条件,在所有子对象中获取符合条件的一个子对象,或者说是获取一个指定名称和类型的子对象,即使有多个符合条件的子对象,也只会输出一个。三个参数的含义为:

参数一是子对象的类型,可以是单个类型变量(QObject)也可以是类型元祖((QPushButton, QLabel))
参数二是子对象的对象名称(或者说是对象ID),可以省略,省略的话就意味着从所有该类型变量中查找,输出查找到的第一个子对象
参数三有两个选择:
	1、Qt.FindDirectChildrenOnly:默认选项,递归查找,在所有子对象中查找
	2、Qt.FindDirectChildrenOnly:只在直接子对象中查找

  findChildren的参数和findChild的一样,只不过是返回所有查找到的子对象,而不是只返回一个,我们可以实验一下这两个函数:

		print(obj0.findChild(QObject))  # 找到obj0的类型为QObject的子对象,找到一个就结束
        print(obj0.findChildren(QObject))  # 找到obj0的类型为QObject的所有子对象,包括子孙对象

  效果如下:
在这里插入图片描述

  我们给obj3设置一个名称:

        obj3.setObjectName("3")

  按名称查找子对象:

print(obj0.findChildren(QObject, "3", Qt.FindChildrenRecursively))  # 找到obj0的类型为QObject,对象名称为3的子对象

结果如下:
在这里插入图片描述

二、具体案例

1、内存管理机制

  所有这些控件其实是一棵QObject继承树,所有的对象都是直接或者间接的继承自QObject,所以说QObjects在一棵对象树中组织他们自己。当创建一个QObject时,如果使用了其他对象作为父对象,那么,他就会被添加到父对象的children列表中。当父对象被销毁时,这个QObject对象也会被销毁。我们可以演示一下,在下面的代码中,obj1是局部变量,执行完函数会立即释放,而ojb2是obj1的子对象,被obj1所指向,不会被自动释放,我们监控obj2的释放信号,当obj2被释放时就打印信息,代码如下:

obj1 = QObject()
obj2 = QObject()

obj2.setParent(obj1)
# 监听obj2对象被释放
obj2.destroyed.connect(lambda : print("obj2对象被释放"))  # 当obj2对象销毁时,执行里面的lambda函数

  结果如下:
在这里插入图片描述

  所以父对象被销毁,子对象也会被销毁。

  对于QWidget组件来说,QWidget组件扩展了QObject对象的父子关系,在QWidget中,当一个控件设置了父控件时,会包含在父控件中,会受到父控件的区域裁剪(也就是子控件大小不能超过父控件),父控件被删除时子控件会自动删除。

  一个对话框,上面有很多操作按钮(取消,ok等),按钮和对话框本身是父子控件关系。我们操作的时候i,是操作的对话框控件本身,而不是其内部的子控件(按钮等)。当对话框被删除时,内部的子控件也会自动的删除。

2、对Qt控件的影响

  还有一个比较重要的作用就是对子控件样式的设置,可以将父控件的某一类子控件全部遍历出来,给每一个子控件都设置对应的样式,就不用一个个的去设置样式了,代码如下:

        win_root = QWidget()
        win_root.setWindowTitle("学习python")
        win_root.resize(500, 500)

        label = QLabel(win_root)  # 设置父控件第一种方式
        label.setText("社会我唐哥")
        # label.setStyleSheet("background-color: cyan;")

        label2 = QLabel(win_root)
        label2.move(50, 50)
        label2.setText("人狠话不多")
        # label2.setStyleSheet("background-color: cyan;")

        btn = QPushButton()
        btn.setText("按钮")
        btn.move(100, 100)
        btn.setParent(win_root)  # 设置父控件第二种方式

        for sub_widget in win_root.findChildren(QLabel):  # 给所有QLabel子对象设置背景颜色
            sub_widget.setStyleSheet("background-color: cyan;")

  效果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_47188967/article/details/130392841
今日推荐