PyQt5编程学习之控件基类QObject深入
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_())