【Qt坐标系统】 全局坐标和相对坐标
QMouseEvent 中有两类坐标系统,一类是窗口坐标,一类是显示器坐标。以下主要介绍mapFromGlobal
、mapFromGlobal
等坐标转换相关的函数。
Widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QLabel>
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QDebug>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
void mouseMoveEvent(QMouseEvent *e); // 鼠标移动事件
bool eventFilter(QObject *obj, QEvent *event); // 事件过滤器
private:
QWidget *m_pSubWidget; // 子窗口
QLabel *m_pLabMousePos; // QMouseEvent::pos()
QLabel *m_pLabMouseGPos; // QMouseEvent::globalPos()
QLabel *m_pLabCursorPos; // QCursor::pos()
QLabel *m_pLabMapToGlobal;// QWidget::mapToGlobal(pos)
QLabel *m_pLabMapFromGlobal; // QWidget::mapFromGlobal(pos)
QLabel *m_pLabMapToParent; // QWidget::mapToParent(pos)
QLabel *m_pLabMapFromParent; // QWidget::mapFromParent(pos)
QLabel *m_pLabMapTo; // QWidget::mapTo(const QWidget * parent, const QPoint & pos)
};
#endif // WIDGET_H
Widget.cpp:
#include "widget.h"
#define STYLE "QLabel{color:green;font-size:18px;}"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->setFixedSize(800, 600);
// 初始化窗口部件
m_pLabMousePos = new QLabel;
m_pLabMouseGPos = new QLabel;
m_pLabCursorPos = new QLabel;
m_pLabMapToGlobal = new QLabel;
m_pLabMapFromGlobal = new QLabel;
m_pLabMapToParent = new QLabel;
m_pLabMapFromParent = new QLabel;
m_pLabMapTo = new QLabel;
m_pLabMousePos->setText("QMouseEvent::pos(): ");
m_pLabMouseGPos->setText("QMouseEvent::pos(): ");
m_pLabCursorPos->setText("QCursor::pos(): ");
m_pLabMapToGlobal->setText("QWidget::mapToGlobal(pos): ");
m_pLabMapFromGlobal->setText("QWidget::mapFromGlobal(pos): ");
m_pLabMapToParent->setText("QWidget::mapToParent(pos): ");
m_pLabMapFromParent->setText("QWidget::mapFromParent(pos): ");
m_pLabMapTo->setText("QWidget::mapTo(parent,pos): ");
m_pLabMousePos->setStyleSheet(STYLE);
m_pLabMouseGPos->setStyleSheet(STYLE);
m_pLabCursorPos->setStyleSheet(STYLE);
m_pLabMapToGlobal->setStyleSheet(STYLE);
m_pLabMapFromGlobal->setStyleSheet(STYLE);
m_pLabMapToParent->setStyleSheet(STYLE);
m_pLabMapFromParent->setStyleSheet(STYLE);
m_pLabMapTo->setStyleSheet(STYLE);
// 子窗口
m_pSubWidget = new QWidget;
m_pSubWidget->setFixedSize(width()/2, height()/2);
m_pSubWidget->setStyleSheet("background: gray;");
m_pSubWidget->installEventFilter(this); // 安装事件过滤器
// Lable布局
QVBoxLayout *pVLayoutLab = new QVBoxLayout;
pVLayoutLab->addWidget(m_pLabMousePos);
pVLayoutLab->addWidget(m_pLabMouseGPos);
pVLayoutLab->addWidget(m_pLabCursorPos);
pVLayoutLab->addWidget(m_pLabMapToGlobal);
pVLayoutLab->addWidget(m_pLabMapFromGlobal);
pVLayoutLab->addWidget(m_pLabMapToParent);
pVLayoutLab->addWidget(m_pLabMapFromParent);
pVLayoutLab->addWidget(m_pLabMapTo);
pVLayoutLab->addStretch();
pVLayoutLab->setSpacing(12);
pVLayoutLab->setContentsMargins(30, 200, 30, 30);
// 主布局
QHBoxLayout *pHLayoutMain = new QHBoxLayout(this);
pHLayoutMain->addWidget(m_pSubWidget);
pHLayoutMain->addLayout(pVLayoutLab);
}
Widget::~Widget()
{
}
// 鼠标移动事件
void Widget::mouseMoveEvent(QMouseEvent *e)
{
// 返回相对这个widget(重载了QMouseEvent的widget)的位置
m_pLabMousePos->setText(QString("QMouseEvent::pos(): %1,%2")\
.arg(e->pos().x()).arg(e->pos().y()));
// 窗口坐标,这个是返回鼠标的全局坐标
m_pLabMouseGPos->setText(QString("QMouseEvent::globalPos(): %1,%2")\
.arg(e->globalPos().x()).arg(e->globalPos().y()));
// 返回相对显示器的全局坐标
m_pLabCursorPos->setText(QString("QCursor::pos(): %1,%2")\
.arg(QCursor::pos().x()).arg(QCursor::pos().y()));
// 将窗口坐标转换成显示器坐标
m_pLabMapToGlobal->setText(QString("QWidget::mapToGlobal(pos): %1,%2")\
.arg(this->mapToGlobal(e->pos()).x()).arg(this->mapToGlobal(e->pos()).y()));
// 将显示器坐标转换成窗口坐标
m_pLabMapFromGlobal->setText(QString("QWidget::mapFromGlobal(pos): %1,%2")\
.arg(this->mapFromGlobal(QCursor::pos()).x()).arg(this->mapFromGlobal(QCursor::pos()).y()));
// 将父类窗口坐标转换成当前窗口坐标
m_pLabMapFromParent->setText(QString("QWidget::mapFromParent(pos): %1,%2")\
.arg(m_pSubWidget->mapFromParent(e->pos()).x()).arg(m_pSubWidget->mapFromParent(e->pos()).y()));
}
//事件过滤器
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
// 判断部件
if (obj == m_pSubWidget)
{
// 判断事件
if (event->type() == QEvent::MouseMove)
{
// 将event强制转换为发生的事件的类型
QMouseEvent *e = static_cast<QMouseEvent*>(event);
// 将窗口坐标获得的pos转换成父类widget的坐标
// 实际测试,与父窗口的相对显示器的全局坐标相等
m_pLabMapToParent->setText(QString("QWidget::mapToParent(pos): %1,%2")\
.arg(this->mapToParent(e->pos()).x()).arg(this->mapToParent(e->pos()).y()));
// 将当前窗口坐标转换成指定parent坐标
m_pLabMapTo->setText(QString("QWidget::mapTo(parent,pos): %1,%2")\
.arg(m_pSubWidget->mapTo(this, e->pos()).x()).arg(m_pSubWidget->mapTo(this, e->pos()).y()));
return true;
}
else // 如果是其他事件,可以进行进一步的处理
{
return false;
}
}
else return QWidget::eventFilter(obj, event);
}
程序运行如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探