4. Event functions in QT --- mouse events, keyboard events, timer events, drawing events

1. Description

In QT controls or windows, if you need to define the functions of the current mouse or keyboard, you can rewrite the corresponding virtual functions in the parent class, mainly including the following:

//键盘按键按下
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. Related code

When using the mouse to move, you need to enable mouse tracking in the constructor

this->setMouseTracking(true);

Keyboard response codes:

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;
    }
}

Mouse button response event:

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. Mouse position

There are two functions to get the mouse position in QMouseEvent , the relevant explanations are as follows:

void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    
    
    //判断鼠标按键类型
    if(event->button() == Qt::LeftButton){
    
    
        
        qDebug()<<event->pos();//输出的是鼠标在相对于本控件左上角的位置
        
        qDebug()<<event->globalPos();//输出的是鼠标相对于整个显示器窗口左上角的位置
        
        qDebug()<<"鼠标双击...";
    }
}

Case: Drag the mouse to move the picture.
Calculation of related positions Auxiliary memory:
insert image description here
To display a picture in Qt, use the QLabel control to load the QPixmap image source. If the picture control needs to support the drag and drop movement of the mouse, you need to define a control yourself, and then re- Mouse control related functions of its parent class.
Therefore, first define a C++ class, inherit QLabel, and rewrite its mousePressEvent and mouseMoveEvent classes. The relevant codes are as follows:
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;
        }
    }

}

Then use a custom class to create a picture control in the main window:

//使用label在窗口上添加一个图片
QPixmap piximg(":/imgs/images/tt.png");
ImageLabel *imgLab = new ImageLabel(piximg,this);
imgLab->move(50,100);//定义初始位置

Show results:

Mouse and keyboard movement custom controls

4. Timer events

If you want to do something at intervals, you can rewrite the timer event function, the example code is as follows:
widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
protected:
    //重写父类的定时器虚函数
    virtual void timerEvent(QTimerEvent* event) override;
    
private:
    //声明两个变量,用于接收定时器的ID号
    int playerTimerID;
    int monsterTimerID;
    
    
};
#endif // WIDGET_H

widget.cpp:

#include "widget.h"
#include <QDebug>
#include <QTimerEvent>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    
    
    //开启玩家定时器
    playerTimerID = this->startTimer(1000);
    //开启怪物定时器
    monsterTimerID = this->startTimer(2000);

	//除了使用startTimer外,也可以使用QTimer类定义定时器对象实现
}

Widget::~Widget()
{
    
    
}

void Widget::timerEvent(QTimerEvent *event)
{
    
    
    if(event->timerId() == this->playerTimerID){
    
    
        qDebug()<< "玩家定时器被触发...";
    }
    if(event->timerId() == this->monsterTimerID){
    
    
        qDebug()<< "怪物定时器被触发...";
    }
}

5. Drawing events

The drawing event function in Qt can draw various images, such as pictures or custom shapes, etc. It needs to rewrite the paintEvent function of the parent class. The sample code is as follows:
widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QColor>
#include <QTimer>

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected:
    //重写父类的绘图事件函数
    virtual void paintEvent(QPaintEvent* event) override;

private:
    //声明一个画家(在一个画布中是可以设置多个画家的)
    QPainter* mPainter;
    //绘制更新定时器
    QTimer* mTimer;

};
#endif // WIDGET_H

widget.cpp:

#include "widget.h"
#include <QDebug>
#include <QTimerEvent>
#include <QColorDialog>
#include <QPixmap>
#include <QImage>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    
    
    //初始化画家
    mPainter = new QPainter(this);
    mTimer= new QTimer(this);
    mTimer->start(100);
    //绘画事件有一个update()函数,当画布发生了新的绘制时,应该调用这个函数让画布更新,这里采用定时器进行刷新
    connect(mTimer,&QTimer::timeout,[this](){
    
    this->update();});
}

Widget::~Widget()
{
    
    
}

void Widget::paintEvent(QPaintEvent *event)
{
    
    
    /*画家准备工作*/
    //创建画笔
    QPen pen(QColor(0,0,125));
    //给画家添加画笔
    mPainter->setPen(pen);
    //开启绘制
    mPainter->begin(this);//即使有多个画家存在,这个开始函数也只需要其中一个画家调用一次就行了

    //开始绘制直线
    mPainter->drawLine(0,0,100,100);

    //绘制矩形
    mPainter->drawRect(100,100,200,50);

    //绘制椭圆
    mPainter->drawEllipse(150,150,50,25);

    //绘制图片
    QImage img(":/imgs/imgs/girl.jpg");
    mPainter->translate(100,200);//画家平移
    mPainter->rotate(45.0);//画家旋转
    mPainter->drawImage(QRect(0,0,100,100),img);
    mPainter->drawImage(QRect(0,0,200,200),img,QRect(200,0,200,200));//指定绘制区域位置
    /*
        第一个参数:(0,0)代表图片的左上角,(200,200)设定图片的大小
        第二个参数:图片源
        第三个参数:(200,0)指定在整张图片上选择的开始绘制点,(200,200)指绘制的尺寸
    */
    
    //结束绘制
    mPainter->end();
}

Guess you like

Origin blog.csdn.net/FY_13781298928/article/details/130763310