4. Funciones de eventos en QT --- eventos de mouse, eventos de teclado, eventos de temporizador, eventos de dibujo

1. Descripción

En los controles o ventanas de QT, si necesita definir las funciones del mouse o teclado actual, puede reescribir las funciones virtuales correspondientes en la clase principal, incluidas principalmente las siguientes:

//键盘按键按下
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. Código relacionado

Al usar el mouse para moverse, debe habilitar el seguimiento del mouse en el constructor

this->setMouseTracking(true);

Códigos de respuesta del teclado:

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

Evento de respuesta del botón del ratón:

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. Posición del ratón

Hay dos funciones para obtener la posición del mouse en QMouseEvent , y las explicaciones relacionadas son las siguientes:

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

Caso: Arrastre el mouse para mover la imagen
Cálculo de posiciones relacionadas Memoria auxiliar:
inserte la descripción de la imagen aquí
Para mostrar una imagen en Qt, use el control QLabel para cargar la fuente de imagen QPixmap Si el control de imagen necesita admitir el movimiento de arrastrar y soltar del mouse , debe definir un control usted mismo y luego volver a controlar las funciones relacionadas con el control del mouse de su clase principal.
Por lo tanto, primero defina una clase C++, herede QLabel y reescriba sus clases mousePressEvent y mouseMoveEvent Los códigos relevantes son los siguientes:
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

Etiqueta de imagen.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;
        }
    }

}

Luego use una clase personalizada para crear un control de imagen en la ventana principal:

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

Mostrar resultados:

Controles personalizados de movimiento de mouse y teclado

4. Eventos de temporizador

Si desea hacer algo a intervalos, puede reescribir la función de evento del temporizador, el código de ejemplo es el siguiente:
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. Dibujar eventos

La función de evento de dibujo en Qt puede dibujar varias imágenes, como imágenes o formas personalizadas, etc. Necesita reescribir la función paintEvent de la clase principal. El código de ejemplo es el siguiente:
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();
}

Supongo que te gusta

Origin blog.csdn.net/FY_13781298928/article/details/130763310
Recomendado
Clasificación