Graphics View画一个可调速的风机(pyqt)

效果如图:
在这里插入图片描述风机具备调节转速的功能,转速通过扇叶旋转的快慢来区别,共分为四档,其中零档为静止状态,而一、二、三档则依次增加转速。在代码中,BlowerWrapper 类包含了可旋转的扇叶、风机外框以及选项三个主要部分。此处有两处关键点值得注意:

  1. BlowerWrapper 选择继承 QObject 的主要原因是为了配合 QPropertyAnimation 的使用,由于普通的 QGraphicsItem 并未继承 QObject,无法使用 QPropertyAnimation 增加动画功能。
  2. fan_item 、option (包括 option1、option2、option3)均使用 setParentItem 方法将 blower_base 设置为它们的父对象,这样便于它们随父对象一起移动。之所以没有使用 group ,是因为使用 group 后,item 将无法接收到鼠标的点击事件。见(https://stackoverflow.com/questions/60476803/how-to-propagate-mouse-events-to-a-qgraphicsitem-in-a-qgraphicsitemgroup)

下面是代码,同步于gitcode https://gitcode.com/m0_37662818/fan

from PyQt5.QtCore import *
from PyQt5.QtCore import pyqtProperty
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *import sysclass MySignal(QObject):fan_singal = pyqtSignal(int)class clickedRectItem(QGraphicsRectItem):def __init__(self, level = None, parent=None):super().__init__(parent)self.level = levelself.signal = MySignal()def mousePressEvent(self, event):if event.button() == Qt.MouseButton.LeftButton:if self.level is not None:self.signal.fan_singal.emit(self.level)return super().mousePressEvent(event)class BlowerWrapper(QObject):def __init__(self, parent=None):super().__init__(parent)fan_pixmap = QPixmap("./fan.png")blower_frame_pixmap = QPixmap("./blower_frame.png")self.fan_item = QGraphicsPixmapItem(fan_pixmap)self.blower_base = QGraphicsPixmapItem(blower_frame_pixmap)self.option1 = clickedRectItem(level=1)self.option2 = clickedRectItem(level=2)self.option3 = clickedRectItem(level=3)self.fan_item.setParentItem(self.blower_base)self.option1.setParentItem(self.blower_base)self.option2.setParentItem(self.blower_base)self.option3.setParentItem(self.blower_base)self.fan_item.setTransformOriginPoint(self.fan_item.boundingRect().center())self.cal_rect()self.animation_init()self.option1.signal.fan_singal.connect(self.animate)self.option2.signal.fan_singal.connect(self.animate)self.option3.signal.fan_singal.connect(self.animate)self.blower_base.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)self.blower_base.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)self.blower_base.setShapeMode(QGraphicsPixmapItem.ShapeMode.BoundingRectShape)self.level = 0def animation_init(self):self.anim = QPropertyAnimation(self, b'rotation')self.anim.setDuration(1600)self.anim.setStartValue(0)self.anim.setEndValue(360)self.anim.setLoopCount(-1)def animate(self,level:int = None):if level is None or level == self.level or level == 0:self.anim.stop()self.set_rect_color(0)self.level = 0returnelse:level = int(level)self.level = levelif level == 1:time = 1600elif level == 2:time = 700elif level == 3:time = 300else:returnself.anim.setDuration(time)self.set_rect_color(self.level)self.anim.start()def cal_rect(self):x_len = self.blower_base.boundingRect().width()y_len = self.blower_base.boundingRect().height()rect_side_length = x_len / 4x_space = (x_len - rect_side_length * 3 ) / 2x1 = 0.0 y1 = y_len + x_space / 2x2 = rect_side_length + x_spacey2 = y_len + x_space / 2x3 = rect_side_length * 2 + x_space * 2y3 = y_len + x_space / 2self.option1.setRect(QRectF(x1, y1, rect_side_length, rect_side_length))self.option2.setRect(QRectF(x2, y2, rect_side_length, rect_side_length))self.option3.setRect(QRectF(x3, y3, rect_side_length, rect_side_length))def _set_rotation(self, angle):self.fan_item.setRotation(angle)def set_rect_color(self, level:int):for item in [self.option1, self.option2, self.option3]:item.setBrush(QColor(255, 255, 255, 255))item.setPen(QColor(0,0,0,255))if level == 1:self.option1.setBrush(QColor(0, 128, 255, 255))self.option1.setPen(QColor(0, 128, 255, 255))elif level == 2:self.option2.setBrush(QColor(0, 128, 255, 255))self.option2.setPen(QColor(0, 128, 255, 255))elif level == 3:self.option3.setBrush(QColor(0, 128, 255, 255))self.option3.setPen(QColor(0, 128, 255, 255))rotation = pyqtProperty(int, fset=_set_rotation)class MainWindow(QGraphicsView):def __init__(self):super().__init__()self.scene_area =  QGraphicsScene(self)self.scene_area.setSceneRect(0,0,300,300)self.setScene(self.scene_area)self.show()self.blower_wrapper = BlowerWrapper()self.scene_area.addItem(self.blower_wrapper.blower_base)self.blower_wrapper.blower_base.setPos(125,110)self.btn = QPushButton("开始")if __name__ == '__main__':app = QApplication(sys.argv)ex = MainWindow()sys.exit(app.exec_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/26357.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SP脏迹Dirt生成器

常用生成器之一 用于模型表面生成污垢和脏迹 添加一个填充图层 添加黑色遮罩 添加生成器 选择Dirt 调整强度 如果UV有接缝就把Use Triplanar打开

AnyDesk 远程桌面控制软件 v9.0.2

AnyDesk 是一款功能强大的跨平台远程桌面控制软件。它支持 Windows、MacOS、Linux 和 Android 系统,同时 iOS 也在其支持范围内。其主要功能包括远程桌面控制,用户能远程访问其他计算机或移动设备,用于远程协作、支持和教授等,可实…

关于延迟任务线程池,Java提供的ScheduledThreadPoolExecutor,Spring提供的ThreadPoolTaskScheduler

今天讲解定时任务、延迟任务的线程池使用方式: 1、从 java 角度 2、从 Spring 框架角度 文章目录 Java提供:ScheduledExecutorService接口(创建延迟任务线程池)① 用法1:1. 重写afterExecute方法2. .schedule()方法调度…

Python PDF文件拆分-详解

目录 使用工具 将PDF按页数拆分 将PDF的每一页拆分为单独的文件 将PDF按指定页数拆分 根据页码范围拆分PDF 根据指定内容拆分PDF 将PDF的一页拆分为多页 在日常生活中,我们常常会遇到大型的PDF文件,这些文件可能难以发送、管理和查阅。将PDF拆分成…

链表的概念及功能实现

一、链表之单向链表 前面我们使用顺序储存结构实现的顺序表,虽然查询的时候很快,但在进行元素的增加或者删除的时候:比较麻烦,需要你去移动大量的元素把数据删除或者增加。 链表里的数据是以结点方式来表示的,每一个结点的组成是…

【Python 语法】算法合集

查找二分查找代码大 O 表示法 广度优先搜索代码 狄克斯特拉算法 递归递归调用栈 分而治之(divide and conquer,D&C)贪心教室调度问题背包问题集合覆盖问题 动态规划背包问题旅游行程最优化 遇到问题时, 如果不确定该如何 高效…

Android 应用开发中,证书、签名和加固简述

在 Android 应用开发中,证书、签名和加固是保障应用安全和完整性的重要机制,各自作用如下: 一、应用证书(Digital Certificate) 作用: 身份标识:证书包含开发者的公钥、组织信息等,用…

在什么情况下需要使用光谱相机呢?

1.需要捕捉不可见光信息时 光谱相机不仅能捕捉可见光,还能记录红外、紫外等波段的光谱信息。以下场景尤其适用: 环境监测:检测水质、空气污染物等肉眼无法观察的物质。 农业监测:分析植物的近红外反射率,判断作物健…

一周一个Unity小游戏2D反弹球游戏 - 球板的发球

前言 本文将实现当游戏开始时球在球板上,且不具备物理性,在Windows平台上通过点击屏幕来球发射,安卓平台上当手指触摸到屏幕上时进行发球,并此时开始具备物理性。 发球逻辑 首先在球板上创建一个球的发射点,新建一个空的游戏物体,并命名为BallPoint,并将其作为SpringBoa…

【算法】图论 —— Floyd算法 python

洛谷 B3647 【模板】Floyd 题目描述 给出一张由 n n n 个点 m m m 条边组成的无向图。 求出所有点对 ( i , j ) (i,j) (i,j) 之间的最短路径。 输入格式 第一行为两个整数 n , m n,m n,m,分别代表点的个数和边的条数。 接下来 m m m 行,每行三…

从实例出发,讲解BLE专业调试工具nRF Connect

nRF Connect是NORDIC Semiconductor提供的一套强大的低功耗蓝牙(BLE)开发工具和应用程序,本文从两个示例着手分析:iBeacon和Eddystone协议的信标Beacon 前置知识:什么是信标Beacon? 信标(Beacon…

[STM32]从零开始的STM32 BSRR、BRR、ODR寄存器讲解

一、前言 学习STM32一阵子以后,相信大家对STM32 GPIO的控制也有一定的了解了。之前在STM32 LED的教程中也教了大家如何使用寄存器以及库函数控制STM32的引脚从而点亮一个LED,之前的寄存器只是作为一个引入,并没有深层次的讲解,在教…

使用Truffle、Ganache、MetaMask、Vue+Web3完成的一个简单区块链项目

文章目录 概要初始化Truffle项目创建编写合约编译合约配置Ganache修改truffle-config.js文件编写迁移文件部署合约使用Truffle 控制台使用MetaMask和VueWeb3与链交互 概要 使用Truffle、Ganache、MetaMask、VueWeb3完成的一个简单区块链项目。 初始化Truffle项目 安装好truf…

在线会议时, 笔记本电脑的麦克风收音效果差是为什么

背景 最近在线面试. 使用腾讯会议或者飞书, 戴耳机参加在线面试, 遇到好几个面试官说我的音质不好. 一直没在意, 后来反思, 应该是电脑哪里出了问题. 排查 先买了一副品牌有线耳机, 测试后本地录制的声音仍然品质很差去掉耳机延长线后, 麦克风品质仍然很差最终找到答案, 原…

通过百度构建一个智能体

通过百度构建一个智能体 直接可用,我不吝啬算力 首先部署一个模型,我们选用deepseek14 构建智能体思考步骤,甚至多智能体; from openai import OpenAIclass Agent:def __init__(self, api_key, base_url, model

解决“request returned Internal Server Error for API route and version xxx”错误

一、问题描述 ragflow/README_zh.md at main infiniflow/ragflowhttps://github.com/infiniflow/ragflow/blob/main/README_zh.md 当我们使用Docker部署ragflow,确认服务器状态时,提示“request returned Internal Server Error for API route and version http://%2F%2F.%…

OpenFlexure记录

https://openflexure.org/projects/microscope/build

游戏引擎学习第131天

仓库:https://gitee.com/mrxiao_com/2d_game_3 运行游戏并识别我们的小问题 今天的工作重点是对游戏引擎进行架构优化,特别是针对渲染和多线程的部分。目前,我们的目标是让地面块在独立线程上进行渲染,以提高性能。在此过程中,我…

Hbase伪分布安装教程,详细版

注意Hbase版本与Hadoop版本的兼容,还有与JDK版本的兼容 本次用到的Hbase为2.4.6版本,Hadoop为3.1.3版本,JDK为JDK8 打开下面的网址查看兼容问题 Apache HBase Reference Guidehttps://hbase.apache.org/book.html#configuration 点击基础先…

使用Hydra进行AI项目的动态配置管理

引言:机器学习中的超参数调优挑战 在机器学习领域,超参数调优是决定模型性能的关键环节。不同的模型架构,如神经网络中的层数、节点数,决策树中的最大深度、最小样本分割数等;以及各种训练相关的超参数,像学习率、优化器类型、批量大小等,其取值的选择对最终模型的效果…