Qt 5.12.3中QCursor::pos()返回坐标异常导致浮动控件无法正确跟随鼠标的问题排查求助
Hey there, let's break down this Qt mouse coordinate offset issue you're facing and work through possible fixes.
First, Let's Fix Your Minimal Example Code
I noticed a couple of syntax errors in your provided code that might be causing basic functionality issues first:
- The constructor definition in your
.cppfile is incorrectly named (moveArea::Area()instead ofArea::Area()) - Your
moveAreamethod is declared but not properly tied to the class.
Here's the corrected version:
// .h file class Area : public QWidget { Q_OBJECT public: explicit Area(QWidget *parent = nullptr) : QWidget(parent) {} // Proper constructor void moveArea(); };
// .cpp file void Area::moveArea() { // We'll adjust this logic based on your widget hierarchy later move(QCursor::pos()); }
Why the Offset Happens (And How to Fix It)
Your core issue—offset that grows with window size—points to two common Qt pitfalls, especially in 5.12.3:
1. Unhandled High-DPI Scaling
Qt 5.12 introduced partial high-DPI support, but it's not always enabled by default. If your app isn't accounting for screen scaling, global coordinates and widget-local coordinates will fall out of sync as you resize the window, leading to proportional offset.
Fix: Add these lines at the very start of your main() function:
int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication app(argc, argv); // Rest of your app initialization return app.exec(); }
2. Confused Coordinate Systems (Parent vs Global)
If your floating widget has a parent widget (instead of being a top-level window), using move(QCursor::pos()) will position it relative to its parent—not the screen. This is a super common mistake that creates offset, especially when the parent widget moves.
Fix: Adjust your moveArea logic based on the widget's parent status:
void Area::moveArea() { QPoint targetPos = QCursor::pos(); // If this widget has a parent, convert global coords to parent-local if (parentWidget()) { targetPos = parentWidget()->mapFromGlobal(targetPos); } move(targetPos); }
3. Verify Mouse Event Coordinate Conversion
When using mouseMoveEvent in your background widget, double-check that you're using the right coordinate mapping:
- If the floating widget is a child of the background widget, use
event->pos()directly (nomapToGlobalneeded—it's already local to the background widget) - If the floating widget is a top-level window,
mapToGlobal(event->pos())is correct, but ensure you're not accidentally applying extra scaling.
Debugging Tips to Confirm the Root Cause
Add these debug prints to trace where the coordinate mismatch happens:
// In your background widget's mouseMoveEvent qDebug() << "Cursor global pos:" << QCursor::pos(); qDebug() << "Background widget global top-left:" << mapToGlobal(QPoint(0,0)); qDebug() << "Floating widget current pos:" << floatWidget->pos();
Compare these values—if the offset matches the background widget's global top-left position, you're definitely mixing up local and global coordinates.
内容的提问来源于stack exchange,提问作者Mykola Tetiuk

