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

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_())

相关文章:

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

效果如图: 风机具备调节转速的功能,转速通过扇叶旋转的快慢来区别,共分为四档,其中零档为静止状态,而一、二、三档则依次增加转速。在代码中,BlowerWrapper 类包含了可旋转的扇叶、风机外框以及选项三个主要…...

基于django图书信息管理系统的搭建(增删改查)

✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示,实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…...

Python 编程题 第四节:斐波那契数列、列表的复制、暂停后输出、成绩评级、统计字符

斐波那契数列 方法一(递归) def f(a):if a1:return 1elif a2:return 1else:return f(a-1)f(a-2) print(f(3)) 方法二(非递归) nint(input()) lst[1,1] for i in range(2,n1):lst.append(lst[i-1]lst[i-2]) print(lst[n-1]) 列…...

【华为OD机考】华为OD笔试真题解析(15)--异常的打卡记录

题目描述 考勤记录是分析和考核职工工作时间利用情况的原始依据,也是计算职工工资的原始依据,为了正确地计算职工工资和监督工资基金使用情况,公司决定对员工的手机打卡记录进行异常排查。 如果出现以下两种情况,则认为打卡异常…...

跟我学C++中级篇——定时器的设计

一、定时器 谈到定时器,理论上讲是各种语言和各种设计都无法避开的一个技术点。对于定时器来说,表面上就是一种时间间隔的处理约定,但对程序来说,可能就是设计层面、接口层面和库或框架以及系统应用的一个大集合。不同的系统&…...

HTTP 请求时传递多部分表单数据

HTTP 请求时传递多部分表单数据(multipart/form-data) --data-raw $------demo11111\r\nContent-Disposition: form-data; name"Filedata"; filename"截屏2025-02-27 15.45.46.png"\r\nContent-Type: image/png\r\n\r\n\r\n------d…...

第J3-1周:DenseNet算法 实现乳腺癌识别

文章目录 一、前言二、前期准备1.设置GPU2.划分数据集 三、搭建网络模型1.DenseLayer模块2.DenseBlock模块3.Transition模块4.构建DenseNet5.构建densenet121 四、训练模型1.编写训练函数2.编写测试函数3.正式训练 五、结果可视化1.Loss与Accuracy图2.模型评估 总结&#xff1a…...

Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)

安装: 1、首先按照此视频的流程一步一步进行安装:(macos版)ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南:https://ragflow.io 3、RAGflow 下载地址:https://github.com/infi…...

【解决】OnTriggerEnter/OnTriggerExit 调用匿名委托误区的问题

开发平台:Unity 开发语言:CSharp 6.0 开发工具:Visual Studio 2022   问题背景 public void OnTriggerEnter(Collider collider) {output.OnInteractionNoticed () > OnInteractionTriggered?.Invoke(); }public void OnTriggerExit(C…...

vscode集成DeepSeek

vscode 扩展 安装 Cline Meet Cline,一个可以使用你的CLI和编辑器的AI助手。 得益于 Claude 3.5 Sonnet的代理编码功能,Cline 可以逐步处理复杂的软件开发任务。借助让他创建和编辑文件、探索大型项目、使用浏览器和执行终端命令(在您授予权限后)的工具&…...

MapReduce编程模型

MapReduce编程模型 理解MapReduce编程模型独立完成一个MapReduce程序并运行成功了解MapReduce工程流程掌握并描述出shuffle全过程(面试)独立编写课堂及作业中的MR程序理解并解决数据倾斜 1. MapReduce编程模型 Hadoop架构图 Hadoop由HDFS分布式存储、M…...

SQL server2022的详细安装流程以及简单使用

鉴于SQL Server2008R2版本过于老旧,本文主要讲述如何安装SQL Server 2022。 本文主要详细介绍SQL server2022的详细安装流程以及简单使用,以《数据库系统概论(第5版)》的第79页—第80页为例,详细介绍如何使用SQL serv…...

Linux的诞生:一场自由与协作的技术革命

Linux的诞生:一场自由与协作的技术革命 在今天的互联网世界,Linux几乎无处不在——从智能手机(Android内核)到超级计算机,从云计算平台到家用路由器,它的身影渗透在技术的各个角落。但这样一个改变世界的操…...

Pytorch为什么 nn.CrossEntropyLoss = LogSoftmax + nn.NLLLoss?

为什么 nn.CrossEntropyLoss LogSoftmax nn.NLLLoss? 在使用 PyTorch 时,我们经常听说 nn.CrossEntropyLoss 是 LogSoftmax 和 nn.NLLLoss 的组合。这句话听起来简单,但背后到底是怎么回事?为什么这两个分开的功能加起来就等于…...

Go入门之文件

以只读方式打开文件 package mainimport ("fmt""io""os" )func main() {file, err : os.Open("./main.go")defer file.Close()if err ! nil {fmt.Println(err)return}fmt.Println(file)var tempSlice make([]byte, 128)var strSlice…...

基因型—环境两向表数据分析——品种生态区划分

参考资料:农作物品种试验数据管理与分析 用于品种生态区划分的GGE双标图有两种功能图:试点向量功能图和“谁赢在哪里”功能图。双标图的具体模型基于SD定标和h加权和试点中心化的数据。本例中籽粒产量的GGE双标图仅解释了G和GE总变异的53.6%,…...

Leetcode2414:最长的字母序连续子字符串的长度

题目描述: 字母序连续字符串 是由字母表中连续字母组成的字符串。换句话说,字符串 "abcdefghijklmnopqrstuvwxyz" 的任意子字符串都是 字母序连续字符串 。 例如,"abc" 是一个字母序连续字符串,而 "ac…...

React(12)案例前期准备

1、创建项目 npx creat-react-app xxx 这里注意 react版本过高会导致antd组件无法安装 需要手动修改pagejson文件中的react和react-demo版本号为 18.2.0 npm i 在配置别名路径 创建craco文件 const path require("path"); module.exports {webpack: {alias: …...

2025年2月28日(RAG)

从图片中的内容来看,用户提到的“RAG”实际上是“Retrieval-Augmented Generation”的缩写,中文称为“检索增强生成”。这是一种结合了检索(Retrieval)和生成(Generation)的技术,用于增强自然语…...

python-leetcode-寻找重复数

287. 寻找重复数 - 力扣(LeetCode) class Solution:def findDuplicate(self, nums: List[int]) -> int:# Step 1: 找到环的相遇点slow nums[0]fast nums[0]# 使用快慢指针,直到相遇while True:slow nums[slow] # 慢指针走一步fast nu…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

ESP32读取DHT11温湿度数据

芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

免费数学几何作图web平台

光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...