1. 说明
在QT的控件或者窗口当中,如果对于当前鼠标或者键盘的功能需要自己定义,可以重写父类当中对应虚函数,主要包括以下几个:
//键盘按键按下
virtual void keyPressEvent(QKeyEvent *event);
//键盘按键抬起
virtual void keyReleaseEvent(QKeyEvent *event);
//鼠标离开
virtual void leaveEvent(QEvent *event);
//鼠标双击
virtual void mouseDoubleClickEvent(QMouseEvent *event);
//鼠标移动
virtual void mouseMoveEvent(QMouseEvent *event);
//鼠标按下
virtual void mousePressEvent(QMouseEvent *event);
//鼠标抬起
virtual void mouseReleaseEvent(QMouseEvent *event);
//鼠标滚轮事件
virtual void wheelEvent(QWheelEvent *event);
2. 相关代码
使用鼠标移动时,需要在构造函数中开启鼠标追踪
this->setMouseTracking(true);
键盘响应代码:
void Widget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_W:
qDebug()<<"模型前进...";
break;
case Qt::Key_S:
qDebug()<<"模型后退...";
break;
case Qt::Key_A:
qDebug()<<"模型向左...";
break;
case Qt::Key_D:
qDebug()<<"模型向右...";
break;
default:
break;
}
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_W:
qDebug()<<"模型停止前进...";
break;
case Qt::Key_S:
qDebug()<<"模型停止后退...";
break;
case Qt::Key_A:
qDebug()<<"模型停止向左...";
break;
case Qt::Key_D:
qDebug()<<"模型停止向右...";
break;
default:
break;
}
}
鼠标按键响应事件:
void Widget::enterEvent(QEvent *event)
{
Q_UNUSED(event);
qDebug()<<"鼠标进入...";
}
void Widget::leaveEvent(QEvent *event)
{
Q_UNUSED(event);
qDebug()<<"鼠标离开...";
}
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
//判断鼠标按键类型
if(event->button() == Qt::LeftButton){
qDebug()<<event->pos();
qDebug()<<"鼠标双击...";
}
}
3. 鼠标位置
在QMouseEvent中有两种获取鼠标位置的函数,相关解释如下:
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
//判断鼠标按键类型
if(event->button() == Qt::LeftButton){
qDebug()<<event->pos();//输出的是鼠标在相对于本控件左上角的位置
qDebug()<<event->globalPos();//输出的是鼠标相对于整个显示器窗口左上角的位置
qDebug()<<"鼠标双击...";
}
}
案例:鼠标拖动图片移动
相关位置计算辅助记忆:
在Qt中显示一张图片,是使用QLabel控件来装载QPixmap图像源,如果图片控件需要支持鼠标的拖拽移动,需要自己定义一个控件,然后重新其父类的鼠标控制相关函数。
所以,先定义一个C++的类,继承QLabel,重写其 mousePressEvent 和 mouseMoveEvent 类,相关代码如下:
ImageLabel.h:
#ifndef IMAGELABEL_H
#define IMAGELABEL_H
#include <QObject>
#include <QLabel>
#include <QWidget>
#include <QPixmap>
class ImageLabel : public QLabel
{
Q_OBJECT
public:
explicit ImageLabel(const QPixmap &pix,QWidget* parent = nullptr);
//重写虚函数
virtual void mousePressEvent(QMouseEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
//重写键盘控制函数
virtual void keyPressEvent(QKeyEvent* event) override;
private:
QPoint mousePressPos;//鼠标点击位置
int mSpeed;//控制移动速度
signals:
};
#endif // IMAGELABEL_H
ImageLabel.cpp:
#include "imagelabel.h"
#include <QMouseEvent>
ImageLabel::ImageLabel(const QPixmap &pix, QWidget *parent)
{
//设置图像源
this->setPixmap(pix);
//设置父控件
this->setParent(parent);
//设置图像比例填充
this->setScaledContents(true);
this->mSpeed = 10;
//处理键盘事件需要先获取焦点
this->setFocusPolicy(Qt::StrongFocus);
}
void ImageLabel::mousePressEvent(QMouseEvent *event)
{
//记录鼠标开始点击时的初始位置向量
mousePressPos = event->pos();
}
void ImageLabel::mouseMoveEvent(QMouseEvent *event)
{
//求鼠标移动偏移量(向量)
QPoint deltaMove = event->pos() - mousePressPos;
//此时鼠标移动了,但是控件本身位置还没有加上偏移量,还未移动
//求窗口新位置(当前位置 + 偏移量)
this->move(this->pos() + deltaMove);
}
void ImageLabel::keyPressEvent(QKeyEvent *event)
{
qDebug()<<"123";
switch (event->key()) {
case Qt::Key_W:{
QPoint pos = this->pos() + QPoint(0,-1) * mSpeed;
this->move(pos);
break;
}
case Qt::Key_S:{
QPoint pos = this->pos() + QPoint(0,1) * mSpeed;
this->move(pos);
break;
}
case Qt::Key_A:{
QPoint pos = this->pos() + QPoint(-1,0) * mSpeed;
this->move(pos);
break;
}
case Qt::Key_D:{
QPoint pos = this->pos() + QPoint(1,0) * mSpeed;
this->move(pos);
break;
}
}
}
然后再在主窗口中使用自定义类创建图片控件即可:
//使用label在窗口上添加一个图片
QPixmap piximg(":/imgs/images/tt.png");
ImageLabel *imgLab = new ImageLabel(piximg,this);
imgLab->move(50,100);//定义初始位置
效果展示:
鼠标键盘移动自定义控件