PyQt5编程学习之控件基类QObject深入

一、QObject描述:

     PyQt几乎所有的类都是从QObject直接或间接继承的,QObject是所有PyQt类的基类,是PyQt对象模型的核心。

二、基类QObject的功能:

(一)操作对象名称、属性:

   1、API介绍:

       (1)setObjectName("唯一名称"):给一个Qt对象设置一个名称,一般这个名称是唯一的,当做对象的ID来使用;

  (2)objectName():获取一个Qt对象的名称;

       (3)setProperty("属性名称",值):给一个Qt对象动态的添加一个属性与值;

  (4)property("属性名称"):获取一个对象的属性值;

  (5)dynamicPropertyNames():获取一个对象中所有通过setProperty()设置的属性名称;

  2、应用实例:

    用于QSS的ID选择器,属性选择器:

  (1)QSS样式文件代码(文件名:QObject.qss):

#ID选择器:#notice,匹配所有的ID为#notice的QLabel控件,这里的ID实际上就是objectName指定的值;
QLabel#notice {
    font-size: 20px;
    color: gray;
    border: 1px solid gray;
    border-radius: 8px;
}
#属性选择器:匹配所有的notice_level属性是normal的且ID为notice的QLabel控件;
QLabel#notice[notice_level="normal"] {
    color: green;
    border-color: green;
}
#属性选择器:匹配所有的notice_level属性是warning的且ID为notice的QLabel控件;
QLabel#notice[notice_level="warning"] {
    color: yellow;
    border-color: yellow;
}
#属性选择器:匹配所有的notice_level属性是error的且ID为notice的QLabel控件;
QLabel#notice[notice_level="error"] {
    color: red;
    border-color: red;
}

  (2)窗口界面创建代码:

from PyQt5.Qt import *

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QObject的对象名称,属性")
        self.resize(500, 500)
        self.setup_ui()

    def setup_ui(self):
        self.QObjectOperate()

    def QObjectOperate(self):

        # *************案例演示***************开始
        with open("QObject.qss", "r") as f:
            qApp.setStyleSheet(f.read())
        #实例化一个QLabel对象label;
        label = QLabel(self)
        #设置对象label对象名为"notice"
        label.setObjectName("notice")
        #设置对象label的"notice_level"属性值为"warning";
        label.setProperty("notice_level", "warning")
        label.setText("属性为warning的Qlabel")

        label2 = QLabel(self)
        label2.move(100, 100)
        label2.setObjectName("notice")
        label2.setProperty("notice_level", "error")
        label2.setText("属性为error的Qlabel")

        label3 = QLabel(self)
        label3.setText("原始格式")
        label3.move(150, 150)

        btn = QPushButton(self)
        btn.setObjectName("notice")
        btn.setText("ID为notice的Qlabel")
        btn.move(50, 50)

        # *************案例演示***************结束


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

  (3)实例代码运行结果:

(二)父子对象的操作:   

   1、API介绍:

  (1)setParent(parent):用于设置父对象 (父对象只能设置一个);

  (2)parent():获取父对象;

  (3)children():获取所有直接子对象;

  (4)findChild(参数1, 参数2, 参数3): 获取某一个指定名称和类型的子对象,参数1(类型:QObject,类型元组:(QPushButton, QLabel),参数2(名称),参数3(查找选项:Qt.FindChildrenRecursively为递归查找,Qt.FindDirectChildrenOnly为只查找直接子对象);

  (5)findChildren(参数1, 参数2, 参数3):获取某多个指定名称和类型的子对象;

  2、应用实例:

   涉及到Qt对象内存管理机制:当使用另一个QObject作为父对象创建QObject时,将自动添加到父对象的children()列表中,父对象会在被删除时自动删除子项;

       (1)父子对象操作实例代码:         

from PyQt5.Qt import *

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QObject的对象名称,属性")
        self.resize(500, 500)
        self.setup_ui()

    def setup_ui(self):
        self.QObject对象的父子关系操作()

    def QObject对象的父子关系操作(self):
        # *************内存管理机制***************开始
        obj1 = QObject()
        self.obj1 = obj1

        obj2 = QObject()
        # 设置obj1为obj2的父对象;
        obj2.setParent(obj1)

        # 监听obj2对象被释放
        obj2.destroyed.connect(lambda: print("obj2对象被释放了"))

        # 父对象会在被删除时自动删除子项obj2;
        del self.obj1

        # *************内存管理机制***************结束

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

      (2)实例代码运行输出结果:

"C:\Program Files\Python35\pythonw.exe" C:/Users/L/PycharmProjects/untitled3/Qobject2.py
obj2对象被释放了

Process finished with exit code 0

 

(三)信号处理:   

   1、API介绍:

          (1)widget.信号.connect(槽):连接信号与槽;

          (2)obj.disconnect():取消连接信号与槽;

          (3)widget.blockSignals(bool):临时(取消)阻止指定控件所有的信号与槽的连接;

            (4)widget.signalsBlocked():信号是否被阻止; 

            (5)widget.receivers(信号):返回连接到信号的接收器数量; 

          2、应用实例:

            (1)实例代码:    

from PyQt5.Qt import *

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QObject的对象名称,属性")
        self.resize(500, 500)
        self.setup_ui()

    def setup_ui(self):
        self.QObject信号的操作()
    def QObject信号的操作(self):
        self.obj = QObject()
        #定义槽
        def obj_name_cao(name):
            print("对象名称发生了改变", name)
        #连接信号与槽
        self.obj.objectNameChanged.connect(obj_name_cao)
        #改变对象名称,发送信号
        self.obj.setObjectName("xxx")
        #取消连接信号与槽
        self.obj.disconnect()
        ##改变对象名称,发送信号,但信号与槽已断开,所以不调用obj_name_cao函数;
        self.obj.setObjectName("xxTT")
        #返回信号是否被阻止
        print(self.obj.signalsBlocked())


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

        (2)代码输出结果:   

"C:\Program Files\Python35\pythonw.exe" C:/Users/L/PycharmProjects/untitled3/Qobject2.py
对象名称发生了改变 xxx
False

 

(四)类型判定:  

       1、API介绍:    

  (1)obj.inherits(父类)     :返回对象是否属于父类
        (2) obj.isWidgetType() :返回对象是否属于QWidget;

       2、实例:

#案例——判定控件是否为标签,将所有标签背景色设为red

from PyQt5.Qt import *
import sys
app=QApplication(sys.argv)
window = QWidget()
a = QLabel(window)
a.move(100,200)
b = QPushButton(window)
b.move(300,200)
c = QLabel(window)
c.move(200,200)
for widget in window.children():
    if widget.inherits("QLabel"):
        widget.setStyleSheet('background-color:red')
window.show()

sys.exit(app.exec_())

 

(五)对象删除:

      1、API介绍:

         obj.deleteLater():删除一个对象时, 也会解除它与父对象之间的关系,deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象,这样做的好处是可以在这些延迟删除的时间内完成一些操作,坏处就是内存释放会不及时。

 

 (六)定时器:

      1、API介绍:

       (1)startTimer(ms, Qt.TimerType) -> timer_id:开启一个定时器;Qt.TimerType:1、Qt.PreciseTimer(精确定时器:尽可能保持毫秒准确);2、Qt.CoarseTimer(粗定时器:5%的误差间隔);3、    Qt.VeryCoarseTimer(很粗的定时器:只能到秒级);

         (2)killTimer(timer_id):根据定时器ID,杀死定时器; 

         (3)timerEvent():定时器执行事件

       2、应用实例:

         代码功能:完成10~0的倒计时,最后输出“stop!"

from PyQt5.Qt import *
import sys
class MyLabel(QLabel):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)          #重新对控件进行封装
        self.setText('10')
        self.setStyleSheet('font-size:22px;')
        self.resize(300,200)
        self.timer_id = self.startTimer(1000)     #在这里生成timer_id
    def timerEvent(self, a0: 'QTimerEvent'):
        current_sec = int(self.text())
        current_sec -= 1
        self.setText(str(current_sec))
        if current_sec == 0:
            self.setText("stop!")
            self.killTimer(self.timer_id)
app=QApplication(sys.argv)
window = QWidget()
window.resize(500,500)
label = MyLabel(window)   #这里实例化的重构后的QObject
label.move(200,200)
window.show()
sys.exit(app.exec_())

 

 

 

 

 

 

 

 

  

posted on 2019-06-01 22:22  阮春义  阅读(2580)  评论(0编辑  收藏  举报

导航