想用QT实现一个很简单的功能:自动获取鼠标坐标,结果因为第一次用QT各种踩坑。
首先增加mouseMoveEvent鼠标事件如下,本以为这样就结束了。
void MoveMouse::mouseMoveEvent(QMouseEvent *e){QString strCoordinate = "坐标: ( " + QString::number(e->x())+ ", " + QString::number(e->y()) + " )";ui->labCoordinate->setText(strCoordinate);}
运行之后,
What???? 坐标出现负值,原来x()和y()是相对于当前窗体控件来的,如果鼠标位置在窗体范围内则是个正值,超出则会出现负,看下介绍,顺便根据介绍找到了全局显示的函数。
但是修改过后,该程序执行后还有问题,那就是虽然增加了鼠标移动事件,但是鼠标不点击时,依然无法获取坐标。这与我本来想法相冲突,我的想法很简单,鼠标到哪,坐标就到哪。
分析原因后发现QT默认是不打开鼠标跟踪的,如果需要该功能,需要通过setMouseTracking事件将其开启,如下介绍:
所以我在程序的结构函数里增加了下面这一句,将鼠标移动打开。如果不设置鼠标移动,事件就不会自动进入mouseMoveEvent事件
MoveMouse::MoveMouse(QWidget *parent): QMainWindow(parent), ui(new Ui::MoveMouse){ui->setupUi(this);this->setMouseTracking(true); //打开鼠标跟踪}
当加完之后,鼠标移动仍然无法自动获取坐标,结合之前的鼠标坐标只在范围内正常,并且文档介绍如果窗体中包含其他控件,则控件也需要打开鼠标跟踪,所以我怀疑是不是必须要设置当前窗体中的鼠标跟踪。
但是窗体应该是什么呢,我看到了构造函数中的一段设置UI的代码ui->setupUi(this),并且当我们自己创建的QMainWindow后,系统会自动在UI的命名空间中创建同名的类MoveMouse,且在UI::MoveMouse里面定义了一些创建窗体相关类。
private:Ui::MoveMouse *ui;{ui->setupUi(this);}
ui_movemouse.h文件中内容如下:
class Ui_MoveMouse{public:QAction *GetCoordinate;QWidget *centralwidget;QLabel *labCoordinate;QStatusBar *statusbar;void setupUi(QMainWindow *MoveMouse){GetCoordinate = new QAction(MoveMouse);GetCoordinate->setObjectName(QString::fromUtf8("GetCoordinate"));centralwidget = new QWidget(MoveMouse);centralwidget->setObjectName(QString::fromUtf8("centralwidget"));labCoordinate = new QLabel(centralwidget);......}}namespace Ui {class MoveMouse: public Ui_MoveMouse {};} // namespace Ui
所以在这个Ui命名空间的类里面,可以找到一个核心类centralwidget,它将返回主窗口的中心窗口部件,那么如果想让鼠标移动事件也通知到它,是不是要将它的鼠标移动属性打开呢,所以接着我尝试了一下:
MoveMouse::MoveMouse(QWidget *parent): QMainWindow(parent), ui(new Ui::MoveMouse){ui->setupUi(this);this->setMouseTracking(true); //打开鼠标跟踪ui->centralwidget->setMouseTracking(true); //打开当前}
执行后,确实鼠标移动可以获取到坐标。当然仍然无法满足我的需求,因为出了窗体后,仍然需要在窗体内按住鼠标才能获取到窗体外的移动坐标,这还是跟事件通知有关系,如果确实想获取怕是只能使用系统级的API才行了。