赞
踩
# 实例化对象 obj = QObject() # 设置名称, 可以重复 obj.setObjectName("名") # 设置属性 obj.setProperty("name", "jack") obj.property("name") # 获取属性值 # 获取所有的动态属性 obj.dynamicPropertyNames() # 设置样式使用qss, 类似css样式表 label = QLabel(window) label.setText("富文本") label.setStyleSheet("color:red; font-size:24px;") # 也可以创建.qss 文件,设置样式 # 控件选择器 QLabel { color: red; font-size: 24px; } // 控件选择器 + id选择器 QPushButton#pp{ color: blue; } //id选择器 + 属性 QPushButton#pp[name="jack"]{ key: value; /*类似css*/ } //也可以直接通过id选择器实现 #pp[name=laufing]{ color: red; background: gray; font-weight: bold; font-style: italic; padding: 2px; margin: 20px; width: 50px; height: 100px; border-style: solid; border-width: 2px; border-color: yellow; text-align: right; } # 使用样式文件 from PyQt5.Qt import qApp with open("style.qss", "r") as f: qApp.setStyleSheet(f.read())
from PyQt5.QtCore import QObject obj1 = QObject() obj2 = QObject() # 设置父对象 obj2.setParent(obj1) # 查看父对象 obj2.parent() # 查看直接子对象 obj1.children() # 查找一个子对象 obj1.findChild(类型, 对象名称, 查找方式) obj1.findChild(QObject, 'laufing', Qt.FindChildrenRecursively) obj1.findChild(QObject, 'laufing', Qt.FindDirectChildrenOnly) obj1.findChildren() # 查找多个子对象 # 导入 from PyQt5.QtCore import Qt Qt.FindChildOption.FindChildrenRecursively
1. 所有的对象都直接或者间接的继承QObject,形参QObject继承树;
2. 当实例化一个QObject对象时,若指定父对象,则该QObject对象则会放入父对象的children列表中
3. 父对象销毁时,其所有的子对象也一起销毁,避免内存泄漏。
# 在一个函数中测试如下:
obj1 = QObject()
obj2 = QObject()
obj2.setParent(obj1)
# 删除信号 连接槽函数
obj1.destroyed.connect(lambda : print("obj1被销毁"))
obj2.destroyed.connect(lambda :print("obj2被销毁"))
反映到控件:
# __author__ = "laufing" from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QLabel, QPushButton from PyQt5.QtGui import QIcon, QPixmap import sys app = QApplication(sys.argv) w1 = QWidget() w1.setWindowTitle("laufing") icon = QIcon() icon.addPixmap(QPixmap("./imgs/dog.jpg"), QIcon.Normal, QIcon.Off) w1.setWindowIcon(icon) w1.resize(400, 500) w1.move(300, 300) label1 = QLabel(w1) label1.setText("label1") label1.resize(30, 20) label1.move(0,20) label2 = QLabel(w1) label2.setText("label2") label2.resize(30, 20) label2.move(35, 20) btn = QPushButton(w1) btn.setText("btn1") btn.resize(30, 20) btn.move(70, 20) # 设置label颜色 for i in w1.findChildren(QLabel): i.setStyleSheet("background-color:cyan") w1.show() exit_code = app.exec_() sys.exit(exit_code)
信号与槽机制, Qt中的核心机制,用户对象之间通信。
当一个控件的状态发生变化时,会发出信号,然后提前连接的槽函数,执行相应的操作。
继承QWidget的控件,都支持信号与槽
机制
信号种类:
内置
QPushButton().pressed, 按下时
QPushButton().clicked 点击时
自定义
pyqtSignal()
槽函数种类
内置 & 自定义函数
建立连接
object.信号.connect(槽函数)
信号与槽 是多对多关系,一个信号可以连接多个槽函数,一个槽函数也可以监听多个信号。
信号也可以连接另一个信号
具体使用:
obj1 = QObject() # 对象被销毁时,发出destroyed信号,绑定槽函数 obj1.destroyed.connect(myFunc) # myFunc定义时,可以接收参数obj, 就是触发信号的对象。 obj1.objectNameChanged.connect(func1) # 槽函数会接收 改后的名字 # 取消信号与槽函数的连接,信号依旧触发,但没有函数的执行 obj1.objectNameChanged.disconnect() # 临时取消 信号与槽的连接 obj1.blockSignals(True) obj1.blockSignals(False) # 恢复 # 查看信号是否阻塞 obj1.signalsBlocked() # 返回True or False # 信号连接的槽函数 数量 obj1.receivers(obj1.objectNameChanged) # 必须传入信号
案例
:
实现窗口中放置一个按钮,点击时,每次更改窗口的标题,如
点击一次, 变为“laufing 1”
点击二次,变为“laufing2”
…
# 核心代码 # click_times = 0 def func1(p): # 声明是全局变量,默认赋值的变量为局部变量 global click_times click_times += 1 # p 为 False ? print("点击按钮,更改窗口的名称:", p, type(p)) # 设置窗口标题(顶级控件) print(w1) w1.setWindowTitle("laufing") def func2(p): print("窗口名字改变:", p) # 声明是全局变量 global click_times # 修改窗口标题 w1.blockSignals(True) # 临时阻塞信号 w1.setWindowTitle("laufing " + str(click_times)) # 设置标题 w1.blockSignals(False) # 取消信号阻塞 # 信号与槽 连接 w1.windowTitleChanged.connect(func2) w1.setWindowTitle("6666") btn.clicked.connect(func1)
# 判定对象是否是某个类型
obj.isWidgetType() # 对象是否 为控件类型
obj.inherits("QWidget") # 返回bool
obj.inherits("QLabel")
deleteLater() 稍后删除一个对象,并与父对象解出关系;
给消息循环发送一个事件,下次循环时再删除;
在本次循环,还可以继续完成相关操作。
# 删除一个对象
obj.deleteLater()
用户的操作会产生消息,放入消息队列中:
操作系统的消息队列, 如键盘事件、鼠标事件
应用程序的消息队列,如控件的点击事件
消息循环不断扫描消息队列,将消息封装为QEvent对象,交给QApplication的notify
方法,进行二次分发,分发给事件源对象的event方法,然后在根据事件的类型分发给事件源对象的事件函数。
# 定义自己的应用类,并实例化 class App(QApplication): def notify(self, receiver, event): # receiver 事件的接收对象(事件源), 如按钮 # event QEvent对象 # 过滤事件 if receiver.inherits("QPushButton") and event.type() == QEvent.MouseButtonPress: print("事件:", receiver, event) return super().notify(receiver, event) # 定义一个按钮类并实例化,点击触发事件 class MyBtn(QPushButton): # QPushButton的源码方法 都是pass? def event(self, event): # 接收事件,并分发给对应的事件函数 if event.type() == QEvent.MouseButtonPress: print("event函数接收事件", event) # 父类的event函数分发 return super(MyBtn, self).event(event) # 事件函数 def mousePressEvent(self, *args, **kwargs): # 这里会发出pressed信号,便于连接 槽函数 print("事件函数执行中....") return super().mousePressEvent(*args, **kwargs) def mouseReleaseEvent(self, e): return super().mouseReleaseEvent(e) def mouseDoubleClickEvent(self, e): print("双击....", e) return super(MyBtn, self).mouseDoubleClickEvent(e) # 单击是?
信号与槽 是对事件的封装
为了对python文件进行加密,会把python模块编译成.pyd文件,供其他人调用。拿到一个.pyd文件,在没有文档说明的情况下,可以试试查看模块内的一些函数和类的用法
,pyd一般使用c/c++ 编写。
from PyQt5.QtCore import Qt # Qt.PreciseTimer 精确毫秒 # Qt.CoarseTimer 5%误差 # 定义自己的类 class MyObject(QObject) def timerEvent(self, *args, **kwargs): print("定时的操作...") # 实例化 obj = MyObject() # 开启定时器, 毫秒 控件对象直接调用 timer_id = obj.startTimer(1000, 类型) # 类型 Qt.PreciseTimer 精确到毫秒 # 取消定时器 obj.killTimer(timer_id)
案例:使用QLabel实现一个倒计时效果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。