010.PyQt5_QObject基类_类型判定&对象删除

类型判定

  • API

    obj.isWidgetType()          # 判断对象是否是控件类型(是否继承自QWidget类)
    obj.inherits('父类')        # 一个对象是否继承(直接或者间接)自某个类
    
  • 示例

    from PyQt5.Qt import
    import sys
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('QObject_类型判断')
            self.resize(980, 500)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
    
        def add_widget(self):
            obj = QObject()
            win = QWidget()
            btn = QPushButton()
            lab = QLabel()
    
            # 给每个对象设置对象名称
            obj.setObjectName('obj')
            win.setObjectName('win')
            btn.setObjectName('btn')
            lab.setObjectName('lab')
    
            # 将对象添加到列表,方便循环判断
            objs = [obj, win, btn, lab]
    
            for o in objs:
                print(f'{o.objectName()} is WidgetType:', o.isWidgetType())
                print(f'{o.objectName()} inherit QObject:', obj.inherits('QObject'))
                print(f'{o.objectName()} inherit QWidget:', obj.inherits('QWidget'))
                print(f'{o.objectName()} inherit QPushButton:', obj.inherits('QPushButton'))
                print()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = Windows()
    
        w.show()
        sys.exit(app.exec_())
    
  • 输出结果

    • 010.PyQt5_QObject基类_类型判定&对象删除_第1张图片

  • 应用场景

    • 过滤筛选控件
  • 案例

    • 创建一个窗口, 包含多个QLabel或其他控件
    • 将包含在窗口内所有的QLabel控件, 设置背景色cyan
      from PyQt5.Qt import *
      import sys
      
      class Windows(QWidget):
          def __init__(self):
              super().__init__()
              self.setWindowTitle('QObject_类型判定案例')
              self.resize(980, 500)
              self.widget_list()
      
          def widget_list(self):
              self.add_widget()
      
      
          def add_widget(self):
              lab1 = QLabel(self)
              lab1.setText('我是一个标签1')
              lab1.move(100, 100)
      
              lab2 = QLabel(self)
              lab2.setText('我是一个标签2')
              lab2.move(100, 150)
      
              lab3 = QLabel(self)
              lab3.setText('我是一个标签3')
              lab3.move(100, 200)
      
              btn1 = QPushButton(self)
              btn1.setText('我是一个按钮1')
              btn1.move(100, 250)
      
              btn2 = QPushButton(self)
              btn2.setText('我是一个按钮2')
              btn2.move(100, 300)
      
              # 方法一
              # for o in self.findChildren(QLabel):
              #     o.setStyleSheet('background-color:cyan;')
      
              # 方法二
              for o in self.children():
                  if o.inherits('QLabel'):
                      o.setStyleSheet('background-color:cyan;')
      
      if __name__ == '__main__':
          app = QApplication(sys.argv)
          w = Windows()
      
          w.show()
          sys.exit(app.exec_())
      
  • 输出结果

    • 010.PyQt5_QObject基类_类型判定&对象删除_第2张图片


对象删除

  • API
    del语句             # 删除变量到对象的引用和变量名称本身
    # 注意del语句作用在变量上,而不是数据对象上
    obj.deleteLater()   # 延迟删除对象
    # deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象
    
  • 删除一个对象时, 也会解除它与父对象之间的关系
  • 这样做的好处是可以在这些延迟删除的时间内完成一些操作,坏处就是内存释放会不及时
  • 示例
    from PyQt5.Qt import
    import sys
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('')
            self.resize(980, 500)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
    
        def add_widget(self):
            obj1 = QObject()
            obj2 = QObject()
            obj3 = QObject()
            obj4 = QObject()
    
            self.obj1 = obj1
    
            obj2.setParent(obj1)    # 设置obj1为obj2的父对象,obj1销毁,obj2将自动销毁
            obj3.setParent(obj2)    # 设置obj2为obj3的父对象,obj2销毁,obj3将自动销毁
            obj4.setParent(obj3)    # 设置obj3为obj4的父对象,obj3销毁,obj4将自动销毁
    
            print(obj1)
            print(obj2)
            print(obj3)
            print(obj4)
    
            obj1.destroyed.connect(lambda :print('obj1被释放了'))
            obj2.destroyed.connect(lambda :print('obj2被释放了'))
            obj3.destroyed.connect(lambda :print('obj3被释放了'))
            obj4.destroyed.connect(lambda :print('obj4被释放了'))
    
            del obj2    # 这里只是删除了栈中的变量到对象的引用和变量名本身。并没有删除堆中的对象
            
            # print(obj2)  # 这里不能再使用obj2这个变量,因为del语句删除变量到对象的引用和变量名称本身
            obj3.deleteLater()  # 延迟删除堆中的对象
            print('del obj2之后')
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = Windows()
    
        w.show()
        sys.exit(app.exec_())
    
  • 输出(在窗体关闭之前)
    \
    \
    \
    \
    del obj2之后
    obj3被释放了
    obj4被释放了
    
    • 从结果可以看到
    • del obj2执行之后,并没有被释放出来。因为del语句仅仅是删除变量到对象的引用和变量名称本身,并没有删除对象本身
    • obj3.deleteLater()之后,obj3和obj4立马被释放了。是因为deleteLater将obj3这个对象给删除了,obj3又是obj4的父对象,父对象被销毁时子对象跟着被销毁,所有obj4也被释放
  • 关于延迟删除示例
    from PyQt5.Qt import
    import sys
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('')
            self.resize(980, 500)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
    
        def add_widget(self):
            obj1 = QObject()
            obj2 = QObject()
            obj3 = QObject()
            obj4 = QObject()
    
            self.obj1 = obj1
    
            obj2.setParent(obj1)    # 设置obj1为obj2的父对象,obj1销毁,obj2将自动销毁
            obj3.setParent(obj2)    # 设置obj2为obj3的父对象,obj2销毁,obj3将自动销毁
            obj4.setParent(obj3)    # 设置obj3为obj4的父对象,obj3销毁,obj4将自动销毁
    
            print(obj1)
            print(obj2)
            print(obj3)
            print(obj4)
    
            obj1.destroyed.connect(lambda :print('obj1被释放了'))
            obj2.destroyed.connect(lambda :print('obj2被释放了'))
            obj3.destroyed.connect(lambda :print('obj3被释放了'))
            obj4.destroyed.connect(lambda :print('obj4被释放了'))
    
            del obj2
            obj3.deleteLater()
            print('del obj2之后')
            print('obj3.deleteLater之后',obj3)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = Windows()
    
        w.show()
        sys.exit(app.exec_())
    
  • 输出结果(窗体关闭之前)
    \
    \
    \
    \
    del obj2之后
    obj3.deleteLater之后 \
    obj3被释放了
    obj4被释放了
    
    • 结果可以看到,obj3.deleteLater()之后,obj3任然能够被打印出来。是因为deleteLater是延迟删除
    • deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象
  • 实例说明
    from PyQt5.Qt import
    import sys
    
    class Windows(QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle('deleteLater')
            self.resize(980, 500)
            self.widget_list()
    
        def widget_list(self):
            self.add_widget()
    
    
        def add_widget(self):
            bnt1 = QPushButton(self)
            bnt1.setText('按钮1')
            bnt1.move(100,100)
    
            bnt2 = QPushButton(self)
            bnt2.setText('按钮2')
            bnt2.move(200, 100)
    
            bnt3 = QPushButton(self)
            bnt3.setText('按钮3')
            bnt3.move(300, 100)
    
            qw = QWidget(self)
            bnt4 = QPushButton()
            bnt4.setParent(qw)
            bnt4.setText('按钮4')
            bnt4.move(400, 100)
    
            del bnt2    # del 仅仅是删除变量到对象的引用和变量名称本身,并没有删除对象本身
            bnt3.deleteLater()  # deleteLater() 直接删除对象
            qw.deleteLater()    # deleteLater() 直接删除父对象之后,子对象自动删除
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = Windows()
    
        w.show()
        sys.exit(app.exec_())
    
  • 展示效果
    • 010.PyQt5_QObject基类_类型判定&对象删除_第3张图片

  • del语句仅仅是删除变量到对象的引用和变量本身,并不删除对象
  • deleteLater()是延迟删除对象本身
    • 010.PyQt5_QObject基类_类型判定&对象删除_第4张图片

你可能感兴趣的:(PyQt5,qt5,pyqt,python,qt,开发语言)