【PyQt】QGraphicsItem的setPos和transformation的平移并不等效

news2024/11/18 6:35:35

1. 结论

今天才知道,改变图元的位置的两个方法:

setPos()

transform.translate()

的本质是不同的!

2. 缘由

在调试代码时,获取某个位置不在原点的图元的坐标总是返回(0,0),百思不得其解,后仔细研究发现。该图元使用的是

transform.translate(x, y)

对图元进行的平移,难道这和 setPos() 函数并不是等效?我使用 

【PyQt】运行QGraphicsItem的Demo代码及三个坐标系的基础用法讲解_pyqt qgraphic 父坐标_qilei2010的博客-CSDN博客

文章中的Demo代码进行了测试,发现二者果然不同。

3. 实验

核心代码如下:

# 1. 通过setPos() 设置图元位置
item = MyItem()                 # 默认的绿色半透明
item.setPos(10,10)
self.scene.addItem(item)

print(item.pos().x())       # 输出 10

# 2. 通过设置 translate() 平移图元
item2 = MyItem()
item2.BrushColor = QColor(231, 55, 55, 127)     # 红色半透明
tf = QTransform()
tf.translate(20,20)           # 平移 20,20
item2.setTransform(tf)
self.scene.addItem(item2)

print(item2.pos().x())       # 输出 0

输出:

 神奇的结果出现了。
使用

transform.translate(x, y)

将图元向右下方平移了20像素,再返回图元的 pos() 居然依然是 (0,0 )。

可以理解为:

transform.translate(x, y)

函数的效果是改变了图元本身的几何特性(平移、变形、缩放),而并非设置图元在父对象中的位置。

看Qt官方对 QTransform 的说明:

The QTransform class specifies 2D transformations of a coordinate system.

A transformation specifies how to translate, scale, shear, rotate or project the coordinate system, and is typically used when rendering graphics.

QTransform类约定了坐标系统的2D变换。

它约定了如何平移、缩放、错切/斜切、旋转或投影坐标系统,主要用来渲染图形元素。

可以理解为是对图元的坐标系统的改变,而不是对图元在父对象或者场景中的位置的改变。

二者不同,但是展示出的图形效果是一样的。

完整代码:

# *******************************************************************************
# * Copyright (c) 2022, <hi_qilei@qq.com><https://blog.csdn.net/qilei2010>
# * update at 2023.01.05 by <hi_qilei@qq.com><https://blog.csdn.net/qilei2010>
# *******************************************************************************
# """ test qt5 example demo , [pycharm, pyqt5, win10]"""

import sys
from PyQt5.QtGui import QPainterPath, QColor, QPen, QTransform
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QMainWindow, QGraphicsItem
from PyQt5.QtCore import Qt, QRectF, QLineF, QPointF


# 自定义图元
class MyItem(QGraphicsItem):
    def __init__(self):
        super().__init__()
        self.BrushColor = QColor(30, 215, 109, 127)     # 默认颜色,半透明绿色。RGBA,127指透明度

    # 必须实现的两个方法 painter 和 boundingRect
    def paint(self, painter, option, widget):
        # 这里可以替换为你要测试的代码
        path = QPainterPath()
        path.addRect(0, 0, 50, 50)  # 矩形,左上角坐标为(0,0),长度30,宽度30
        painter.setBrush(self.BrushColor)  # 设置画刷颜色-用于填充颜色,
        painter.drawPath(path)  # 绘制path

    def boundingRect(self):
        return QRectF(0, 0, 50, 50)  # 图元边界,用于scene刷新图元


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.scene = QGraphicsScene()

        # 1. 通过setPos() 设置图元位置
        item = MyItem()                 # 默认的绿色半透明
        item.setPos(10,10)
        self.scene.addItem(item)
        print(item.pos().x())       # 输出 10

        # # 1. 通过设置 translate() 平移图元
        item2 = MyItem()
        item2.BrushColor = QColor(231, 55, 55, 127)     # 红色半透明
        tf = QTransform()
        tf.translate(20,20)           # 平移 10,10
        item2.setTransform(tf)
        self.scene.addItem(item2)
        print(item2.pos().x())       # 输出 0

        # 有view就要有scene
        self.view = QGraphicsView()
        self.view.setScene(self.scene)

        # 设置场景中心点为(0,0),绘制坐标为(0,0)的图元会出现在窗口的正中心,方便新手绘制图元
        self.view.scene().setSceneRect(-100, -100, 200, 200)  # 场景的左上角为(-100,100)宽200高200

        # 绘制xOy直角坐标系x、y坐标轴,方便新手
        self.view.scene().setBackgroundBrush(QColor("white"))  # 设置场景scene背景色为灰色
        self.view.scene().addLine(QLineF(QPointF(-100, 0), QPointF(100, 0)))  # x轴线
        self.view.scene().addLine(QLineF(QPointF(0, -100), QPointF(0, 100)))  # y轴线

        # 设置view可以进行鼠标的拖拽选择
        self.view.setDragMode(self.view.RubberBandDrag)

        self.setMinimumHeight(400)  # 窗口最小高度
        self.setMinimumWidth(400)  # 窗口最小宽度
        self.setCentralWidget(self.view)
        self.setWindowTitle("Graphics Demo")


def demo_run():
    app = QApplication(sys.argv)
    demo = MainWindow()
    # 适配 Retina 显示屏(选写).
    app.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
    app.setAttribute(Qt.AA_EnableHighDpiScaling, True)
    # ----------------------------------
    demo.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    demo_run()

<全文完>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

prometheus监控之pushgateway

prometheus监控之pushgateway 文章目录 prometheus监控之pushgatewaypushgateway是什么pushgateway使用场景架构图安装pushgateway配置说明 prometheus配置pushgateway的使用数据推送默认格式入门操作较为复杂数据的推送一次性推送多个指标(命令行方式)一次性推送多条数据&…

QML地图绘制虚线

QML提供了MapPolyline用于在地图上绘制线段&#xff0c;该线段是实线&#xff0c;因此我使用Canvas自定义绘制的方式在地图上绘制线段&#xff0c;如图&#xff1a; 鼠标在地图上点击后&#xff0c;在点击位置添加图标 &#xff0c;当有多个图标被添加到地图上后&#xff0c;计…

让你立刻学会指针

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C语言和数据结构 &#x1f33c;博客专栏&#xff1a;C语言学习 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&am…

NumberPicker分析(三)

NumberPicker分析(三) 这一节主要用来分析NumberPicker的事件处理及滚动 NumberPicker继承自LinearLayout&#xff0c;是一个ViewGroup&#xff0c;ViewGroup事件处理的顺序大致如下&#xff1a; dispatchTouchEventonInterceptTouchEventonTouchEvent 另外&#xff0c;源码中…

ADSP21489之CCES开发笔记(十)

ADI21489定时器设计思路&#xff1a; 1、配置Power management control register. 2、定义时钟中断调用函数接口及实现。。 3、指定时钟中断间隔。 4、启用时钟timer。 demo代码实现2~4,如下代码 #include <services/int/adi_int.h> #include <stdio.h> #include &…

consul集群搭建教程 - 单机器集群

简言 1. 上一篇博客我们讲了consul多机器集群的部署&#xff0c;consul集群搭建教程 - 多机集群_YZF_Kevin的博客-CSDN博客 2. 很多同学没有多个机器&#xff0c;只想在单台机器上实验下consul集群&#xff0c;所以这篇博客我们讲单台机器的consul集群部署 3. consul的各个版…

mapreduce打包提交执行wordcount案例

文章目录 一、源代码1. WordCountMapper类2. WordCountReducer类3. WordCountDriver类4. pom.xml 二、相关操作和配置1. 项目打包2. 带参测试3. 上传打包后的jar包和测试文档4. 增大虚拟内存5.启动集群6.在hdfs上创建输入文件夹和上传测试文档Hello.txt7. 利用jar包在hdfs实现文…

TX-LCN:分布式事务框架

文章目录 概念LCN模式创建父工程parent创建子工程TxManager: 管理事务创建子工程: Eureka Server 注册中心创建子工程: book: 被远程调用方创建子工程: student: 远程调用方 TCC模式在lcn的基础上创建子工程: redistest在student 调用 redistest 概念 TX-LCN由两大模块组成&am…

设计模式:行为型模式 - 策略模式

文章目录 1.概述2.结构3.案例实现4.优缺点5.使用场景6.JDK源码解析 1.概述 先看下面的图片&#xff0c;我们去旅游选择出行模式有很多种&#xff0c;可以骑自行车、可以坐汽车、可以坐火车、可以坐飞机。 作为一个程序猿&#xff0c;开发需要选择一款开发工具&#xff0c;当然…

基于SpringBoot医养中心管理系统

有需要请私信或看评论链接哦 可远程调试 SpringBoot医养中心管理系统 一 介绍 基于SpringBoot医养中心管理系统-登录角色分为用户和管理员。用户登录后可查看个人信息/家人情况&#xff0c;生活情况和收费标准。管理员登录后台可进行账号管理&#xff0c;健康管理&#xff0c…

如何在Android面试中脱颖而出,高频Android面试题解析,帮你快速拿到Offer

Android面试就“小技巧” 了解自己的技能水平&#xff1a;在面试前&#xff0c;确保你对所面试的职位的技能要求有足够的了解&#xff0c;并检查自己的技能水平是否符合这些要求。熟悉面试流程&#xff1a;了解面试过程中可能会遇到的问题&#xff0c;并为每个问题准备好回答。…

itop-3568开发板驱动学习笔记(20)中断线程化

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 中断线程化简介中断线程化 API中断线程化实验 中断线程化简介 中断线程化也是中断下文的一种方式&#xff0c;与工作队列和软中断不同的是&#xff0c;中断线程只用于这个中断&#xff0c;当发生中断的时候…

Java基于POI动态合并单元格

Java使用poi导出excel 前言1.Excel和POI对象对应关系&#xff1a;2.POI创建Excel的步骤 一、引入依赖二、示例1.准备数据2.创建Excel工作簿对象3.给excel创建表头4.填充数据5.浏览器访问下载excel6.完整代码 前言 有个需求需要后端将数据导出为excel。并且excel中需要合并单元格…

linux安装java1.8

前言 安装java1.8是为了适配pyspark&#xff0c; 出现错误&#xff1a;pyspark.sql.utils.IllegalArgumentException: Unsupported class file major version 55\56\57\60 通过“java -version”看一下java版本&#xff0c;发现版本是java11&#xff0c;应该安装1.8才对 1、…

GaussDB工作级开发者认证—第二章GaussDB数据库应用程序开发指引

一. 驱动概述 GaussDB客户端接入认证&#xff0c;GaussDB支持以下三种认证方式&#xff1a;基于主机的认证口令认证SSL加密 二. JDBC接口介绍 1. JDBC概述 Java数据库连接&#xff08;JDBC&#xff09;是Java标准&#xff0c;它提供了从Java连接到关系数 据库的接口&#x…

C++智能指针shared_ptr详解

智能指针shared_ptr详解 一、简介二、底层原理2.1、引用计数2.2、shared_ptr的构造和析构2.3、shared_ptr的共享和拷贝2.4、循环引用问题 三、shared_ptr的使用3.1、创建一个shared_ptr3.2、共享一个shared_ptr3.3、使用删除器3.4、解除关联 四、使用示例总结 一、简介 C智能指…

软件测试拿了几个20K offer,分享一波面经

1、你的测试职业发展是什么?  测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&#xff0c;不…

MySQL笔记-函数,约束

本文标签 : 数据库函数 约束 目录 一、函数 1.字符串函数. 2.数值函数. 3.日期函数. 4.流程函数 二、约束 1.概述 2.约束演示 3.外键约束 1.概念 : 2. 实现: 3.删除/更新行为: 三、总结 一、函数 1.字符串函数. 实现: -- 函数演示 ---- 语法: select 函数(参数);-- …

跨域和网关通俗小白理解

跨域 跨域就是协议域名端口不同的服务器不能互相请求&#xff0c;企业级解决办法一般是通过Nginx反向代理实现 我们服务&#xff0c;线上都是通过S3服务器的Nginx反向代理解决跨域问题&#xff0c;因为Nginx和服务端沟通属于服务器之间的问题&#xff0c;不像浏览器有同源策略…

哇塞,炫云的智能优化太厉害啦!渲染费用竟然大幅降低了!

你有没有遇到过因为设置参数错误而导致云渲染费用突然飙升的情况呢&#xff1f;或者不知道自己设置的参数是否过高&#xff1f;现在&#xff0c;这些问题都可以轻松解决了&#xff0c;因为炫云的渲染质量功能非常智能和人性化。根据不同用户需求&#xff0c;它将参数优化分为五…