QT学习笔记—事件处理

Qt是以事件来驱动的,类似鼠标点击、按下键盘等都是属于事件。Qt将所有的事件都抽象成QEvent类,其它各种各样的事件都继承自QEvent

在这里插入图片描述

QEvent继承自QWidget

通过Qt助手搜索QWidget查看Protected Functions一栏可以支持的事件。事件基本都是受保护的虚函数。虚函数C++中用于实现多态,所以可以重写实现对特定事件的处理。


窗口事件

  • 离开事件

    [virtual protected] void QWidget::leaveEvent(QEvent *event)
    
  • 进入事件

    [virtual protected] void QWidget::enterEvent(QEvent *event)
    
  • 事件分发

    [virtual protected] bool QWidget::event(QEvent *event)
    
class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

public:
    void leaveEvent(QEvent *event); //重写的离开事件
    void enterEvent(QEvent *event); //重写进入事件
    bool event(QEvent *event); //重写事件分发
private:
    Ui::Widget *ui;
};

void Widget::leaveEvent(QEvent *event)
{
    
    
    qDebug() << "鼠标进入了主窗口";
}

void Widget::enterEvent(QEvent *event)
{
    
    
    qDebug() << "鼠标离开了主窗口";
}

 bool Widget::event(QEvent *event)
{
    
    
    if (event->type() == QEvent::MouseButtonDblClick)   //鼠标双击事件
    {
    
    
        qDebug() << "双击了主窗口";

        return true;   //表示我已经处理,不向下分发MouseButtonDblClick事件
                       //可以对事件做一个拦截
    }
    return QWidget::event(event);  //其他情况默认处理
}

鼠标事件

鼠标事件相关的类:QMouseEvent

  • 鼠标移动事件:

    [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
    
  • 鼠标按下事件:

    [virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
    
  • 鼠标释放事件:

    [virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
    
  • 鼠标双击事件:

    [virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
    
class myPushButton : public QPushButton
{
    
    
    Q_OBJECT
public:
    explicit myPushButton(QWidget *parent = nullptr);

public:
     void mouseMoveEvent(QMouseEvent *event);
     void mousePressEvent(QMouseEvent *e);
     void mouseDoubleClickEvent(QMouseEvent *event);
     void mouseReleaseEvent(QMouseEvent *e);
signals:

public slots:
};
#include "mypushbutton.h"
#include <QDebug>

myPushButton::myPushButton(QWidget *parent) : QPushButton(parent)
{
    
    
    setMouseTracking(true);   //设置鼠标追踪,不按下鼠标键就触发鼠标移动事件
}

void myPushButton::mouseDoubleClickEvent(QMouseEvent *event)
{
    
    
    qDebug() << "鼠标双击了按钮";
}

//设置鼠标追踪才能看到鼠标移动事件
void myPushButton::mouseMoveEvent(QMouseEvent *event)
{
    
    
    qDebug() << "鼠标在按钮上移动";
}

void myPushButton::mousePressEvent(QMouseEvent *e)
{
    
    
    qDebug() << "鼠标按下了按钮";
}

void myPushButton::mouseReleaseEvent(QMouseEvent *e)
{
    
    
    qDebug() << "鼠标释放了按钮";
}

鼠标分左键、右键、中键等,对鼠标事件有时还得区分是哪个键双击、按下,还有组合键的情况。

  • Qt助手搜索QMouseEvent,可知鼠标判断是哪个键执行的函数:
Qt::MouseButton QMouseEvent::button() const
//Returns the button that caused the event.//返回引起事件的按钮
    
Qt::MouseButtons QMouseEvent::buttons() const
//Returns the button state when the event was generateds
  • Qt::MouseButton枚举:

    主要是以下几个

1、Qt::LeftButton    //左键
2、Qt::RightButton   //右键
3、Qt::MidButton     //中键
.....
void myPushButton::mouseDoubleClickEvent(QMouseEvent *event)
{
    
    
    if (event->button() == Qt::LeftButton)
    {
    
    
        qDebug() << "鼠标左键双击了按钮";
    }
}

//设置鼠标追踪才能看到鼠标移动事件
void myPushButton::mouseMoveEvent(QMouseEvent *event)
{
    
    
    qDebug() << "鼠标在按钮上移动";
}

void myPushButton::mousePressEvent(QMouseEvent *event)
{
    
    
    if (event->button() == Qt::RightButton)
        qDebug() << "鼠标右键按下了按钮";
}
void myPushButton::mousePressEvent(QMouseEvent *event)
{
    
    
//    if (event->button() == Qt::RightButton)
//        qDebug() << "鼠标右键按下了按钮";
//    if (event->buttons() == Qt::RightButton)
//    {
    
    
 //        qDebug() << "鼠标右键按下了按钮";
//    }
    
    if (event->buttons() & Qt::RightButton)
    {
    
    
         qDebug() << "鼠标右键按下了按钮";
    }
}

对鼠标的处理中还有很多其他的处理,可以精准到对鼠标所在的位置。

  • 鼠标位置相关的方法:

    int x() const
    int y() const
        
    QPoint pos() const
    
    void myPushButton::mouseMoveEvent(QMouseEvent *event)
    {
          
          
        qDebug() << "鼠标在按钮上移动";
        QString str = QString("鼠标的位置:x = %1 y = %2").arg(event->x()).arg(event->y());
        qDebug() << str;
    }
    
    

定时器事件

定时器相关的类:QTimerQTimerEvent

  • 定时器事件

    [virtual protected] void QTimer::timerEvent(QTimerEvent *e)
    

启动定时器两种方式:

  • 第一种:
int QObject::startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
//返回值是定时器的id
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);

    timerId1 = startTimer(1000);  //启动定时器
    timerId2 = startTimer(2000);
}
//重写定时器事件
void Widget::timerEvent(QTimerEvent *event)
{
    
    
    if (event->timerId() == timerId2)
    {
    
    
        qDebug() << "2s时间到";
    }

    if (event->timerId() == timerId1)
    {
    
    
        qDebug() << "1s时间到";
    }
}
  • 第二种:

    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
          
          
        ui->setupUi(this);
    
        QTimer *timer = new QTimer;  //创建一个定时器
        timer->start(3000);  //启动
    
        connect(timer, &QTimer::timeout, [=](){
          
          
            qDebug() << "3s时间到";
        });  //设置信号、槽,槽使用lamda表达式
    }
    

键盘事件

键盘事件的类:QKeyEvent

  • 键盘按下

    [virtual protected] void QWidget::keyPressEvent(QKeyEvent *event)
    
  • 键盘释放

    [virtual protected] void QWidget::keyReleaseEvent(QKeyEvent *event)
    
  • 判断哪个按键按下

    int QKeyEvent::key() const
    //Returns the code of the key that was pressed or released.
    

    通过Qt::Key里面的枚举值判断是哪个按键按下。

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

     void keyPressEvent(QKeyEvent *event);
     void keyReleaseEvent(QKeyEvent *event);

private:
    Ui::Widget *ui;
};
void Widget::keyPressEvent(QKeyEvent *event)
{
    
    
    if (event->key() &  Qt::Key_Enter)   //如果按下回车键
    {
    
    
        qDebug() << "按下了回车键";
    }
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    
    
    if (event->key() &  Qt::Key_Enter)   //如果按下回车键
    {
    
    
        qDebug() << "释放了回车键";
    }
}

设置焦点窗口:

当只有一个窗口时,键盘事件就是给当前窗口的。当有多个窗口时,需要指定一个焦点窗口来接收键盘事件。

void QWidget::setFocus(Qt::FocusReason reason);
//reason 焦点切换的原因,一般是Qt::OtherFocusReason即可

事件过滤器

事件只能在自己的类中处理,如果其它对象想知道某个窗口的事件,需要给窗口安装事件过滤器

安装事件过滤器:

void QObject::installEventFilter(QObject *filterObj)
//filterObj 监控者

事件过滤函数:

[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)
//watch 监控对象
//event 事件
//返回true表示过滤事件,false表示不过滤
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    cirX = 0;


    connect(ui->pushButton, &QPushButton::clicked, [=](){
    
    
        cirX++;
//        update();    //手动绘图,调用update更新
        repaint();
    });

    ui->pushButton->installEventFilter(this);  //安装事件过滤器
}

//重写事件过滤处理函数
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    
    
    if (watched == ui->pushButton)
    {
    
    
        if (event->type() == QEvent::MouseButtonDblClick)
        {
    
    
            qDebug() << "过滤按钮上的鼠标双击事件";
            return true;   //返回true表示过滤事件
        }
    }
    return QWidget::eventFilter(watched, event);   //其他情况使用默认处理
}

绘图事件

绘图事件:

[virtual protected] void QWidget::paintEvent(QPaintEvent *event)

绘图事件函数是一直被调用。用户不重写绘图事件就什么都不绘制。当用户重写该函数就执行用户的实现。

void Widget::paintEvent(QPaintEvent *event)
{
    
    
    QPainter *myPainter = new QPainter(this);

    QPen pen(QColor(255, 0, 0)); //创建一个画笔
    pen.setWidth(3);    //设置画笔宽度

    myPainter->setPen(pen);  //设置画笔

    QBrush brush(Qt::cyan); //设置画刷
    //设置画刷风格
    brush.setStyle(Qt::Dense7Pattern);
    //让画家使用画刷
    myPainter->setBrush(brush);

    myPainter->drawLine(20, 20, 50, 60);  //画线

    myPainter->drawEllipse(40, 40, 50, 60); //画圆
}

重绘:

[slot] void QWidget::repaint()  //立即重启
    
[slot] void QWidget::update()  //不立马重绘,而是加入消息循环来调度
#include <QPen>
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    cirX = 0;

	//通过按钮手动绘图
    connect(ui->pushButton, &QPushButton::clicked, [=](){
    
    
        cirX++;
//        update();    //手动绘图,调用update更新
        repaint();
    });
}

Widget::~Widget()
{
    
    
    delete ui;
}

void Widget::paintEvent(QPaintEvent *event)
{
    
    
    QPainter *myPainter = new QPainter(this);

    QPen pen(QColor(255, 0, 0)); //创建一个画笔
    pen.setWidth(3);    //设置画笔宽度

    myPainter->setPen(pen);  //设置画笔

    myPainter->drawEllipse(40+cirX, 40, 50, 60); //画圆。圆会随着按钮移动而移动
}

猜你喜欢

转载自blog.csdn.net/qq_36413982/article/details/107879999
今日推荐