在学习QT事件时接触到鼠标移动事件,联想到一些录屏软件中的鼠标跟踪效果,就写了一个简单的鼠标跟踪器。
1. 鼠标移动事件
首先就是解释一下所谓的事件,即QT已经预先定义好的某些信号的处理动作函数。若QT工程中要使用这些事件函数,需要重写事件函数。事件函数无需用户主动调用,也无需用户将其和某个信号关联,这些事件函数就是对应信号的槽函数,当信号发出,事件函数会被系统自动调用。
QT中封装了鼠标移动事件mouseMoveEvent(QMouseEvent *),调用其中的方法即可获取当前鼠标的坐标
2. 绘图事
获取鼠标当前的坐标之后,在坐标周围画一个圆就行了,需要使用QT中的绘图事件QPaintEvent。绘图事件相对于QT中其他的填充背景方法比较灵活,因此可以设置绘图圆的圆心跟随鼠标移动,实现效果。
代码如下:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPoint>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void mouseMoveEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
private:
Ui::Widget *ui;
QPoint point;//新坐标原点
QPoint orgPoint;//原坐标原点
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPalette>//调色板类
#include <QPainter>
#include <QBrush>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
img = QImage(":/222.jpg");
//设置鼠标跟踪属性生效
this->setMouseTracking(true);
}
Widget::~Widget()
{
delete ui;
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
//1.设置当前鼠标相对于默认坐标原点(左上角)的坐标值
orgPoint.setX(event->x());
orgPoint.setY(event->y());
//2.设置当前鼠标相对于新坐标原点(左下角)的坐标值
point.setX(orgPoint.x()-20);
point.setY(this->height()-orgPoint.y()-20);
//3.将当前鼠标坐标值(新)设置成窗体标题
QString str;
str.sprintf("%d %d",point.x(),point.y());
this->setWindowTitle(str);
//4.将当前鼠标坐标值放到labelx和labely中
ui->label_x->setText(QString::number(point.x()));
ui->label_y->setText(QString::number(point.y()));
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter pt1(this);
//图片自适应窗体
QImage img1 = img.scaled(this->width(),this->height());
//参数:图片在窗体的位置x和y,绘制的图片对象,绘制图片的起始位置,绘制图片在窗体的宽度和高度
pt1.drawImage(0,0,img1,0,0,this->width(),this->height());
//定义画笔
QPainter *pt = new QPainter(this);
//设置画笔颜色
pt->setPen(QPen(Qt::black));
//1.画大矩形
pt->drawRect(20,20,this->width()-40,this->height()-40);
//3.设置label_x和label_y的位置和大小
ui->label_x->setGeometry(orgPoint.x(),0,20,20);
ui->label_y->setGeometry(0,orgPoint.y(),20,20);
//4.给label设置边框
pt->drawRect(orgPoint.x(),0,20,20);
pt->drawRect(0,orgPoint.y(),20,20);
//圆心位置在当前鼠标的位置上
point_cir = QPoint(orgPoint.x(),orgPoint.y());
//填充圆
pt->setBrush(QBrush(Qt::red));
pt->drawEllipse(point_cir,20,20);
update();
}
这里设置了两个坐标原点一个是左上角,另外一个是左下角可以选择;另外给当前窗体框出了一个矩形,并将坐标值实时显示在矩形外的label中。
效果就是这样的:
遗憾的是实际上鼠标的移动和圆的移动之间是有一定延迟的,鼠标越快,延迟越大。