自己关于Qt坐标的错误使用

今天在公司做项目的时候,对转换坐标系出现了一些差解。

我建的窗口是一个QWidget   A 里面有两个QLabel,

另有一个跟Label同样大小的窗口控件B;

B的状态窗口C。

由B生成的对象分别显示到A的两个Label中。 在我显示C时 我打算显示到B的边缘,当鼠标移动到B上时显示出来。


在显示C时 因为A无法显示完,因此需要绝对坐标来放置。(在B中)

第一次犯错  mapToGlobal(   mapToParent(this->pos() )  ) 来获取最终坐标                                ///  this->pos() 就是获取当前模块在父窗口中的坐标

第二次犯错 发现后  修改为 mapToGlobal( this ->pos()  )///  发现坐标转换后叠加了窗口中的坐标    坐标不准确 偏差为相对于客户区的坐标   


错误的原因是 此函数是基于当前模块转换,  以上函数都是当前模块(B)的成员函数,但我当做全局函数来用。

正确获取   直接使用 mapToGlobal(QPoint(0, 0)) 就行了;



个人错误 仅供参考

<think>好的,我现在需要回答用户关于Qt框架中坐标变换的实现和用法的问题。首先,我需要回顾用户提供的引用内容,确保理解正确,并结合自己的知识来组织回答。 首先,用户提供的引用1到4都涉及Qt坐标系统、变换方法以及实际应用示例。引用2详细解释了Qt的三个坐标系:逻辑坐标系、窗口坐标系和物理坐标系,以及它们之间的转换关系。引用3提到了具体的坐标转换方法,比如mapFromGlobal和mapFromParent。引用4提到了组合模式和渐变填充的应用,这可能与绘图效果有关,但坐标变换是基础。 我需要先理清Qt坐标系统的基本结构,然后解释各个变换方法的作用和使用场景。根据引用2,Qt坐标系统转换过程是逻辑坐标系→窗口坐标系→物理坐标系。默认情况下,这三个坐标系是相同的,但通过setWindow和setViewport可以改变映射关系。另外,引用3中的mapFromGlobal等方法用于同部件之间的坐标转换,这也是坐标变换的一部分。 接下来,我应该分步骤解释Qt中的坐标变换实现: 1. **坐标系统结构**:三个坐标系的定义和转换流程。 2. **基本变换方法**:平移、旋转、缩放、剪切,这些是QPainter提供的变换操作。 3. **窗口与视口变换**:setWindow和setViewport的作用,如何调整坐标系的范围和映射。 4. **部件间坐标转换**:如mapToGlobal、mapFromParent等方法的使用。 5. **变换状态管理**:save()和restore()的作用,确保变换状态的保存和恢复。 6. **实际应用示例**:给出一个简单的代码示例,展示如何应用这些变换。 同时,用户要求生成相关问题,我需要根据内容提出相关问题,比如性能优化、组合模式、实际应用场景等。 需要确保回答结构清晰,使用中文,并正确应用引用标识。例如,在提到窗口和视口变换时,引用[^2],在提到部件间转换时引用[^3],在提到组合模式时引用[^4]。 另外,检查是否所有的数学表达式都正确使用了$...$或$$...$$格式。例如,在解释矩阵变换时可能需要用到矩阵表达式,但根据用户提供的示例,可能需要数学公式,但如果有,要确保格式正确。 最后,确保回答真实可靠,结合引用内容和Qt官方文档的知识,避免错误信息。</think>### Qt框架中的坐标变换实现与用法详解 Qt坐标变换系统通过**逻辑坐标系、窗口坐标系、物理坐标系**的三层结构实现图形绘制的灵活性[^2],并提供了平移、旋转、缩放等基础变换操作[^1]。以下是具体实现与用法的分步说明: --- #### 一、Qt坐标系统核心结构 1. **逻辑坐标系** - 开发者直接操作的坐标系,如绘制矩形时使用的$(x, y)$坐标。 - 通过`setWindow()`定义逻辑坐标系到窗口坐标系的映射范围[^2]: ```cpp painter.setWindow(-100, -100, 200, 200); // 将逻辑坐标系范围设为[-100,100] ``` 2. **窗口坐标系** - 中间层坐标系,通过`setViewport()`定义其在物理设备上的显示区域[^2]: ```cpp painter.setViewport(50, 50, 400, 400); // 将窗口映射到物理坐标系的(50,50)位置,大小为400x400 ``` 3. **物理坐标系** - 实际设备(如屏幕)的像素坐标系。 --- #### 二、基础坐标变换方法 通过`QPainter`类实现图形变换: 1. **平移** ```cpp painter.translate(100, 50); // 将原点向右移动100像素,向下移动50像素 ``` 2. **旋转** ```cpp painter.rotate(45); // 绕当前原点顺时针旋转45度 ``` 3. **缩放** ```cpp painter.scale(2, 0.5); // X轴放大2倍,Y轴缩小为1/2 ``` 4. **剪切** ```cpp painter.shear(0.2, 0); // X轴方向倾斜0.2倍 ``` --- #### 三、部件间坐标转换 通过`mapTo()`/`mapFrom()`系列方法实现同控件的坐标转换: ```cpp // 将全局坐标转换为子部件的局部坐标 QPoint globalPos = QCursor::pos(); QPoint childPos = childWidget->mapFromGlobal(globalPos); // [^3] ``` --- #### 四、变换状态管理 使用`save()`和`restore()`管理变换堆栈: ```cpp painter.save(); // 保存当前状态(如平移后的原点) painter.translate(10, 10); painter.drawRect(0, 0, 50, 50); painter.restore(); // 恢复原点位置 ``` --- #### 五、实际应用示例 ```cpp void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setPen(Qt::red); // 1. 平移后绘制矩形 painter.save(); painter.translate(100, 100); painter.drawRect(0, 0, 50, 50); // 实际位置在物理坐标(100,100)-(150,150) painter.restore(); // 2. 旋转文本 painter.translate(200, 200); painter.rotate(45); painter.drawText(0, 0, "旋转45度"); } ``` --- #### 六、组合模式与高级效果 通过`setCompositionMode()`实现叠加效果,如渐变与透明度混合[^4]: ```cpp QLinearGradient gradient(0, 0, 100, 0); gradient.setColorAt(0, Qt::yellow); gradient.setColorAt(1, Qt::green); painter.setBrush(gradient); painter.setCompositionMode(QPainter::CompositionMode_Screen); painter.drawEllipse(0, 0, 100, 100); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值