当前位置: 首页 > news >正文

【PySide6】信号(signal)和槽函数(slot),以及事件过滤器

说明

在PYQT中,父控件可以通过两种方式响应子控件的事件:

  • 通过信号(signal)和槽函数(slot)机制连接子控件和父控件
  • 父控件可以通过设置eventFilter()方法来监听响应子控件的事件

一、信号(signal)和槽函数(slot)

示例

在PYQT中,每个组件都可以发出信号(signal),表示某个事件发生了。父组件可以通过connect()方法将子组件的信号连接到自己的槽函数(slot)中,从而响应这个事件。
举个例子,在一个界面中,可能有一个按钮(btn),当用户点击按钮时,需要将用户的操作记录到日志中。这时,可以在父组件中定义一个槽函数(log),然后将按钮的clicked信号连接到这个槽函数中:

class MyWindow(QWidget):def __init__(self):super().__init__()# 创建一个按钮self.btn = QPushButton('Click me', self)# 将按钮的clicked信号连接到log槽函数中self.btn.clicked.connect(self.log)def log(self):# 记录日志print('Button clicked')

QThread 多线程

在 PyQt 中,可以使用信号和槽机制来实现不同线程之间的通信。在使用 QThread 时,可以将 QThread 的子类化与信号和槽机制结合使用来实现多线程编程。

以下是一个简单的示例,展示了如何在 QThread 中使用信号和槽函数:

from PySide6.QtCore import QThread, Signalclass Worker(QThread):finished = Signal()  # 定义一个信号def __init__(self):super().__init__()def run(self):# 这里可以执行耗时操作self.finished.emit()  # 发射信号class MainWindow(QMainWindow):def __init__(self):super().__init__()self.worker = Worker()self.worker.finished.connect(self.on_finished)  # 连接信号和槽函数def on_finished(self):# 这里可以进行 UI 更新等操作passdef start_work(self):self.worker.start()

在上面的示例中,我们定义了一个 Worker 类,它继承自 QThread 类。Worker 类中定义了一个 finished 信号,用于在耗时操作完成后发射信号。在 MainWindow 类中,我们创建了一个 Worker 对象,并将其 finished 信号连接到 on_finished 槽函数上。在 start_work 函数中,我们启动了 Worker 线程,耗时操作完成后会发射 finished 信号,从而触发 on_finished 槽函数的执行。

以下是另一个简单的示例,展示了如何在 QThread 中使用信号和槽函数:
```python
from PySide6.QtCore import QThread, Signal, Slotclass WorkerThread(QThread):new_data = Signal(str)def __init__(self):super(WorkerThread, self).__init__()def run(self):for i in range(20):data = "Data: " + str(i)self.new_data.emit(data)self.msleep(1000)class MainWindow(QMainWindow):def __init__(self):super(MainWindow, self).__init__()self.worker_thread = WorkerThread()self.worker_thread.new_data.connect(self.on_new_data)self.start_button = QPushButton("Start")self.start_button.clicked.connect(self.worker_thread.start)self.layout = QVBoxLayout()self.layout.addWidget(self.start_button)self.central_widget = QWidget()self.central_widget.setLayout(self.layout)self.setCentralWidget(self.central_widget)@Slot(str)def on_new_data(self, data):print("Received data:", data)

在上面的示例代码中,创建了一个WorkerThread类,该类继承自QThread,并包含一个new_data信号。在run方法中,通过emit方法发送new_data信号。在MainWindow类中,创建了一个WorkerThread实例,并将其new_data信号连接到on_new_data槽函数。当用户单击Start按钮时,调用worker_thread.start方法启动新线程。

在on_new_data槽函数中,打印接收到的数据。注意,on_new_data方法带有一个字符串参数,该参数类型必须与new_data信号的参数类型相同。这是通过在on_new_data方法上添加@Slot(str)装饰器来实现的。

总的来说,在pyside6中使用信号和槽函数来使用QThread非常简单,只需将信号连接到槽函数即可。但请注意要在正确的线程中使用信号和槽函数。如果将信号发射到不同的线程中,可能会导致应用程序崩溃或未定义的行为。

二、事件过滤器

在PySide6中,如果在一个widget中创建了另一个widget,那么新widget默认是不会响应父控件的事件的。如果需要让新widget能够响应控件的事件,可以通过设置事件过滤器来实现。

事件过滤器是一种机制,允许我们在任意widget上监视和过滤所有事件,包括父控件的事件。通过设置事件过滤器,可以将父组件接收到的事件传播到子组件中。

示例代码一,在父控件,子控件分别设置事件过滤器

以下是示例代码:
在这里插入图片描述

import sysfrom PySide6.QtCore import QEvent
from PySide6.QtGui import Qt, QPainter
from PySide6.QtWidgets import QWidget, QApplication, QVBoxLayout, QLabel, QHBoxLayoutclass ChildWidget(QWidget):def __init__(self, parent=None):super().__init__(parent)self.setObjectName('ChildWidget')self.setFixedSize(100, 100)self.label = QLabel("Child")# 子组件布局self.child_layout = QVBoxLayout(self)self.child_layout.addWidget(self.label, 1, alignment=Qt.AlignCenter)def eventFilter(self, obj, event):if obj == self and event.type() == QEvent.MouseButtonPress:print('ChildWidget eventFilter', event)return super().eventFilter(obj, event)# 设置子控件颜色def paintEvent(self, event):painter = QPainter(self)painter.fillRect(self.rect(), Qt.red)class ParentWidget(QWidget):def __init__(self):super().__init__()self.setObjectName('ParentWidget')self.setAutoFillBackground(True)self.setFixedSize(200, 200)# 事件过滤器self.child = ChildWidget(self)self.child.installEventFilter(self)self.installEventFilter(self)# 父组件布局self.parent_layout = QHBoxLayout(self)self.parent_label = QLabel("Parent")self.parent_layout.addWidget(self.child, 1)self.parent_layout.addWidget(self.parent_label, 1, alignment=Qt.AlignCenter)def eventFilter(self, obj, event):if obj == self and event.type() == QEvent.MouseButtonPress:print('ParentWidget eventFilter', event)return self.child.eventFilter(obj, event)if __name__ == '__main__':app = QApplication([])parent = ParentWidget()parent.show()sys.exit(app.exec())

示例代码二,在父控件事件中设置所有子控件的事件

在这里插入图片描述

from PySide6.QtCore import Signal, QObject, QEvent
from PySide6.QtWidgets import QWidget, QApplication, QTextEdit, QVBoxLayout, QPushButton, QHBoxLayoutclass ChildWidget(QWidget):def __init__(self, parent=None):super().__init__(parent)self.setObjectName('ChildWidget')self.layout = QHBoxLayout(self)self.child_button = QPushButton("Child")self.layout.addWidget(self.child_button)class ParentWidget(QWidget):def __init__(self):super().__init__()self.setObjectName('ParentWidget')self.layout = QHBoxLayout(self)# parent_buttonself.parent_button = QPushButton("Parent")self.parent_button.installEventFilter(self)# ChildWidgetself.child = ChildWidget(self)self.child.child_button.installEventFilter(self)self.layout.addWidget(self.child)self.layout.addWidget(self.parent_button)self.layout.stretch(2)def eventFilter(self, obj, event):if obj == self.child.child_button and event.type() == QEvent.MouseButtonPress:print('ChildWidget eventFilter', event)elif obj == self.parent_button and event.type() == QEvent.MouseButtonPress:print('ParentWidget eventFilter', event)return super().eventFilter(obj, event)if __name__ == '__main__':app = QApplication([])parent = ParentWidget()parent.show()app.exec()

相关文章:

【PySide6】信号(signal)和槽函数(slot),以及事件过滤器

说明 在PYQT中,父控件可以通过两种方式响应子控件的事件: 通过信号(signal)和槽函数(slot)机制连接子控件和父控件父控件可以通过设置eventFilter()方法来监听响应子控件的事件 一、信号(signal)和槽函数(slot) 示例 在PYQT中,每个组件都…...

canal admin管理端配置(二)

下载安装 下载地址: 下载解压即可 配置 修改canal.admin-1.1.5\conf\application.yml server:port: 8089 #端口根据是否冲突修改 spring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT8spring.datasource:address: 192.0.16.12:3306#数据库ip和端口…...

Servlet 生命周期

Servlet的生命周期有四个阶段:加载并实例化、初始化、请求处理、销毁。主要涉及到的方法有init、service、doGet、doPost、destory等 加载并实例化 Servlet容器负责加载和实例化Servelt。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一…...

redis集群模式登陆

总结redis单机模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口redis集群模式时,登陆redis的命令格式: ./redis-cli -h 地址 -p 端口 -c举例1:redis单机模式下登陆rootubuntu:/usr/local/redis/redis-7.0.0/b…...

04-useMemo 、React.memo、useCallback

useMemo 、React.memo、useCallback 一、useMemo 基本用法 缓存数据,模拟 Vue 中的计算属性。 同样useMemo跟vue中component一样,也是有缓存的,会将结果缓存下来 import React, { useMemo, useState } from react;export default functio…...

windows下安装emqx Unable to load emulator DLL@if ===/ SET data_dir=“

1.报错内容 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin>emqx start Unable to load emulator DLL (I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\erts-12.3.2.9\bin\beam.smp.dll) 此时不应有 SET。 I:\0-software\02-emqx\emqx-5.0.19-windows-amd64\bin&…...

Redis常见问题(未完待续)

Redis常见问题Redis为什么快 ?Redis为什么快 ? 根据官方数据,Redis 的 QPS 可以达到约 100000(每秒请求数); 基于内存 对于磁盘数据库来说,首先要将数据通过 IO 操作读取到内存里再读取&#x…...

2024秋招BAT核心算法 | 详解图论

图论入门与最短路径算法 图的基本概念 由节点和边组成的集合 图的一些概念: ①有向边(有向图),无向边(无向图),权值 ②节点(度),对应无向图,…...

凝聚共识,锚定未来 | 第四届OpenI/O 启智开发者大会NLP大模型论坛成功举办!

2023年2月24日下午,第四届OpenI/O启智开发者大会NLP大模型分论坛在深圳人才研修院隆重举办。该论坛以“开源集智创新探索中文NLP大模型生态发展”为主题,众多业内人士和研发者在此共享NLP领域的前沿动态和研发经验,畅想中国NLP领域的发展前景…...

99.【Git】

Git(一)、什么是版本控制1.什么是版本控制2、常见的版本控制工具(二)、版本控制分类1、本地版本控制2、集中版本控制 SVN3、分布式版本控制 Git(三)、Git与SVN的主要区别1、Git历史(四)、Git下载与环境配置1.git下载2、启动Git(五)、常用的Linux命令1.Linux常用命令(六)、Git必…...

Linux驱动交叉编译把驱动文件放入开发板,以及printk函数打印级别

上一篇介绍了一个最简单的驱动程序和驱动程序大体结构,但那还是用本地编译只能在Ubuntu上运行,我们该怎么编译一个能加载到开发板上呢,就需要交叉编译,交叉编译通常都是在嵌入式开发中使用到的。 交叉编译 理解交叉编译前先了解…...

力扣(LeetCode)433. 最小基因变化(2023.03.07)

基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是 ‘A’、‘C’、‘G’ 和 ‘T’ 之一。 假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。 例如,“AACCGGTT”…...

网络基础(2)

目录1. 端口号2. 套接字socket3. 网络通信3.1 sockaddr与sockaddr_in3.2 接口服务端3.2.1 创建套接字,打开网络文件3.2.2 给该服务器绑定端口和ip(特殊处理)3.2.3 初始化相关服务器3.2.4 提供服务客户端3.2.5 绑定3.2.6 使用服务4. makefile实…...

掌握Spring Cloud Gateway:构建高性能API网关的原理和实践

Spring Cloud Gateway 是一个基于 Spring Boot 的 API 网关,用于构建微服务架构中的网关服务。它提供了统一的路由、请求转发、过滤器、负载均衡、熔断等功能,帮助开发者更好地管理和控制微服务系统的请求流量。 本文将介绍 Spring Cloud Gateway 的原理…...

NAST概述

一、NATS介绍 NATS是由CloudFoundry的架构师Derek开发的一个开源的、轻量级、高性能的,支持发布、订阅机制的分布式消息队列系统。它的核心基于EventMachine开发,代码量不多,可以下载下来慢慢研究。 不同于Java社区的kafka,nats…...

【JS知识点】——原型和原型链

文章目录原型和原型链构造函数原型显式原型(prototype)隐式原型(\_\_proto\_\_)原型链总结原型和原型链 在js中,原型和原型链是一个非常重要的知识点,只有理解原型和原型链,才能深刻理解JS。在…...

c盘怎么清理到最干净?有什么好的清理方法

c盘怎么清理到最干净?有什么好的清理方法?清理C盘空间是电脑维护的重要步骤之一。C盘是Windows操作系统的核心部分,保存了许多重要的系统文件,因此空间不足会影响计算机的性能和稳定性。下面是一些清理C盘空间的方法 一.清理临时文件 在使用…...

day26_HTML

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、二阶段介绍 二、HTML 零、 复习昨日 见代码 一、二阶段介绍 第一阶段: 基础入门 java基本语法编程基础(方法,数组)面向对象编程常用类高级(IO,线程,新…...

深度剖析C语言预处理

致前行的人: 人生像攀登一座山,而找寻出路,却是一种学习的过程,我们应当在这过程中,学习稳定冷静,学习如何从慌乱中找到生机。 目录 1.程序翻译过程: 2.字符串宏常量 3.用宏定义充当注释符号 4…...

【WPF 值转换器】ValueConverter 进阶用法

【WPF 值转换器】ValueConverter 进阶用法介绍基类实现子类实现效果介绍 值转换器在WPF开发中是非常常见的,当然不仅仅是在WPF开发中。值转换器可以帮助我们很轻松地实现,界面数据展示的问题,如:模块隐藏显示、编码数据展示为可读…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...

uniapp中使用aixos 报错

问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

Qt Quick Controls模块功能及架构

Qt Quick Controls是Qt Quick的一个附加模块&#xff0c;提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中&#xff0c;这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构&#xff0c;与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...