GUI编程--PyQt5--QObject

本文介绍了Qt编程中的关键概念,包括QObject对象的名称和属性设置,父子关系,内存管理机制,信号与槽的使用,自定义信号,以及对象类型的判断。同时,讲解了Qt的事件处理机制,特别是如何处理和响应用户操作产生的事件。最后,讨论了QObject的定时器功能,展示了如何在应用程序中实现定时任务。此外,提供了具体的代码示例,如窗口标题的动态改变和倒计时效果的实现。
摘要由CSDN通过智能技术生成

对象的名称和属性

在这里插入图片描述

# 实例化对象
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())

在这里插入图片描述
其他参考

QObject对象的父子关系

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

Qt的内存管理

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被销毁"))

反映到控件:

  1. 当一个控件设置了父控件,那么就被受父控件的管理(大小、生命周期),父控件删除,子控件也被删除
  2. 案例,关闭一个对话框,则删除其内部的所有的子控件。

案例

  1. 创建一个空白窗口,添加多个QLabel、QPushButton等控件
  2. 所有的QLabel都设置cyan背景色
  3. 在添加一个QLabel 控件 也是具有相同的背景色
# __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)

 
 

QObject 信号的操作

信号与槽机制, 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)

QObject 类型判定

# 判定对象是否是某个类型
obj.isWidgetType()  # 对象是否 为控件类型
obj.inherits("QWidget")   # 返回bool
obj.inherits("QLabel")

QObject 对象的删除

deleteLater() 稍后删除一个对象,并与父对象解出关系;
给消息循环发送一个事件,下次循环时再删除;
在本次循环,还可以继续完成相关操作。

# 删除一个对象
obj.deleteLater()

事件机制

用户的操作会产生消息,放入消息队列中:
操作系统的消息队列, 如键盘事件、鼠标事件
应用程序的消息队列,如控件的点击事件

消息循环不断扫描消息队列,将消息封装为QEvent对象,交给QApplicationnotify方法,进行二次分发,分发给事件源对象的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++ 编写。
 
 

QObject的定时器

在这里插入图片描述

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实现一个倒计时效果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: PyQt5是Python编程语言的一种GUI库,用于创建桌面应用程序。它是由Riverbank Computing开发的,为开发者提供了丰富的GUI元素和功能,使他们能够轻松地构建各种用户界面。 而PyQt5-sip是PyQt5的一部分,是一个用于生成Python绑定代码的代码生成器。它将C++头文件转换为Python模块,使开发者能够在Python中使用C++框架和库。PyQt5-sip负责将QObject、QEvent等和对象转换为Python可调用的代码。 PyQt5PyQt5-sip之间的关系可以简单地理解为:PyQt5-sip是PyQt5的一个重要组成部分,它提供了与C++代码的交互能力,使得PyQt5能够与底层的Qt库进行通信。在安装PyQt5时,PyQt5-sip会自动包含在内,因此我们不需要单独安装或管理PyQt5-sip。 对于开发者而言,了解PyQt5PyQt5-sip的版本非常重要。这是因为PyQt5PyQt5-sip的版本必须相互兼容,以确保代码能够正确地运行。如果您使用的PyQt5版本与PyQt5-sip不兼容,可能导致一些错误或功能失效。因此,在使用PyQt5时,我们需要确保选择合适的PyQt5-sip版本与之配套。 总结来说,PyQt5是一款强大的GUI库,而PyQt5-sip是PyQt5的重要组成部分,用于生成与C++代码交互的Python绑定代码。了解并选择合适的PyQt5PyQt5-sip版本对于确保顺利开发和运行PyQt5应用程序是必要的。 ### 回答2: PyQt5PyQt5-sip 是两个与 Python 语言结合使用的库。这两个库的版本是相互关联的。 PyQt5 是基于 Qt 库的 Python 封装,可以用于开发图形界面应用程序。它提供了丰富的 GUI 组件和功能,可以通过 Python 代码来创建和控制界面。 PyQt5-sip 是 PyQt5 的依赖库,它是用于处理 Python 对象和 Qt 对象之间的转换和通信的工具。它实际上是 PyQt5 的一部分,负责生成包装 Qt 的 Python 的代码。 这两个库的版本是相关的,因为 PyQt5-sip 的版本必须与 PyQt5 的版本相匹配。如果版本不匹配,可能会导致库之间的不兼容性和错误。因此,在使用 PyQt5 时,你需要根据 PyQt5 的版本来选择相应的 PyQt5-sip 版本。 通常,你可以通过以下命令来安装最新版本的 PyQt5PyQt5-sip: ``` pip install PyQt5 ``` 然后,PyQt5-sip 会自动安装为 PyQt5 的依赖项。 总的来说,PyQt5PyQt5-sip 是用于 Python GUI 开发的重要工具。在使用时需要注意版本匹配,以确保两者能够正常工作。 ### 回答3: PyQt5是一个Python绑定的Qt库,它允许开发者通过Python语言来开发跨平台的图形用户界面(GUI)应用程序。 而pyqt5-sip是PyQt5的一个SIP模块,用于将C++库和Python语言进行交互。它是一个必需的依赖项,需要与PyQt5配套使用。 PyQt5-sip是由Riverbank Computing提供的一款工具,它通过SIP(一个Python/C++通信框架)来实现C++和Python的互操作性。SIP工具将C++代码转换成Python代码,使得开发人员可以在Python中直接调用C++代码和库。 在使用PyQt5时,我们需要安装和配置PyQt5pyqt5-sip两个软件包。PyQt5提供了丰富的Qt和方法,用于创建各种型的GUI应用程序。而pyqt5-sip则是在PyQt5中作为连接器的角色,它将C++对象转换为Python对象,并使得Python能够直接调用C++代码和库,实现了二者之间的桥梁。 需要注意的是,PyQt5pyqt5-sip的版本需要匹配,才能保证二者的兼容性。因此,在安装PyQt5pyqt5-sip时,应该选择合适的版本,并确保它们能够正确地配合使用。 总的来说,PyQt5是一个功能强大的库,用于开发Python GUI应用程序,而pyqt5-sip是其所依赖的一个模块,用于实现C++和Python之间的互操作性。它们共同工作,帮助我们使用Python语言开发出跨平台的GUI应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值