0
点赞
收藏
分享

微信扫一扫

Qt事件系统

岁月不饶人老不正经 04-03 22:30 阅读 2

第三章Qt事件系统

文章目录

1.事件系统

在Qt中,事件是派生抽象QEvent类的对象,它表示应用程序内发生的事情,或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理。
Qt程序需要在main函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始Qt的事件循环。执行后,程序将进入事件循环来监听应用程序的事件,当事件发生时,Qt将创建一个事件对象。

事件是如何传递的

事件类型

#include <QWidget>
#include <QMouseEvent>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    //鼠标事件
    void mouseDoubleClickEvent(QMouseEvent *)override;
    void mousePressEvent(QMouseEvent *)override;
    void mouseReleaseEvent(QMouseEvent *)override;
    void mouseMoveEvent(QMouseEvent *)override;

    //按键事件
    void keyPressEvent(QKeyEvent *)override;
    void keyReleaseEvent(QKeyEvent * )override;

    //窗口事件
    void closeEvent(QCloseEvent *) override;
    void hideEvent(QHideEvent *)override;
    void resizeEvent(QResizeEvent *)override;

    //焦点事件
    void focusInEvent(QFocusEvent*)override;
    void focusOutEvent(QFocusEvent*)override ;

    void contextMenuEvent(QContextMenuEvent*)override;

    //程序状态改变事件
    void changeEvent(QEvent*)override;

    //定时器事件
    void timerEvent(QTimerEvent*)override;
};

事件处理

#include "Widget.h"
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setMouseTracking(false);//启用鼠标追踪
    this->setFocus();
    new QPushButton("按钮",this);
    this->startTimer(10);//10毫秒
}

Widget::~Widget() {}

void Widget::mouseDoubleClickEvent(QMouseEvent *)
{
    qInfo()<<"鼠标双击";
}

void Widget::mousePressEvent(QMouseEvent *)
{
    qInfo()<<"鼠标按下";
}

void Widget::mouseReleaseEvent(QMouseEvent *)
{
    qInfo()<<"鼠标释放";
}

void Widget::mouseMoveEvent(QMouseEvent *)
{
    static int16_t i=0;
    qInfo()<<"鼠标移动"<<i++;
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    qInfo()<<event->text()<<"按键已按下";
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    auto k=event->key();
    qInfo()<<k<<"按键已弹起";
}

void Widget::closeEvent(QCloseEvent *)
{
    qInfo()<<"窗口关闭";
}

void Widget::hideEvent(QHideEvent *)
{
    qInfo()<<"窗口隐藏";
}

void Widget::resizeEvent(QResizeEvent *)
{
    qInfo()<<"窗口大小改变";
}

void Widget::focusInEvent(QFocusEvent *)
{
    qInfo("有焦点");
}

void Widget::focusOutEvent(QFocusEvent *)
{
    qInfo("失去焦点");
}

void Widget::contextMenuEvent(QContextMenuEvent *)
{
    qInfo()<<"收到信号,弹出菜单";
}

void Widget::changeEvent(QEvent *e)
{
    if(e->type()==QEvent::WindowStateChange)
        qInfo()<<"发生改变";
}

void Widget::timerEvent(QTimerEvent *)
{
    static qint32 x=0,y = 0;
    this->move(x++%600+500,y++%800);
}

 bool event(QEvent *event) override;
 
bool Widget::event(QEvent *event)
{
    if(event->type()==QEvent::Type::MouseButtonPress)
        return true;//屏蔽了MouseButtonPress事件
    return QWidget::event(event);	//把事件交给父类处理
}

发送事件

  • 自定义事件
#include <QWidget>
#include <QMouseEvent>
#include <QEvent>

class MyCustomEvent:public QEvent
{
public:
    MyCustomEvent():QEvent(QEvent::Type::User)
    {
        info = "自定义事件";
    }
    QString getMessage()
    {
        return info;
    }
private:
    QString info;
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
protected:
    //鼠标事件
    void mousePressEvent(QMouseEvent *)override;

    //自定义事件
    void customEvent(QEvent *event)override;

};

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    resize(640,480);
}


void Widget::mousePressEvent(QMouseEvent *)
{
    qInfo()<<"鼠标按下";
    MyCustomEvent* ce = new MyCustomEvent;
    qApp->sendEvent(this,ce);
}

void Widget::customEvent(QEvent *event)
{
    if(event->type()==QEvent::User)
    {
        auto ce = dynamic_cast<MyCustomEvent*>(event);
        if(!ce)
            return;
        qInfo()<<ce->getMessage();
    }
}
  • sendEvent和postEvent的区别

2.事件传播机制

事件接受和忽略

事件分发

事件过滤

用事件过滤器实现鼠标拖动无边框窗口案例

#include <QWidget>
#include <QMouseEvent>
#include <QEvent>
#include <QPushButton>

class Widget : public QWidget
{
    Q_OBJECT

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


    //事件过滤处理器
    bool eventFilter(QObject *watched, QEvent *event)override;
private:
    QPoint pressPos;

#include "Widget.h"
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    resize(640,480);
    setWindowFlag(Qt::FramelessWindowHint);//设置无边框
    installEventFilter(this);//在对象上安装事件过滤器,如果不装,过滤器重写无效
}

Widget::~Widget() {}




bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched==this)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            auto me=dynamic_cast<QMouseEvent*>(event);
            pressPos = me->pos();
            return true;
        }
        else if(event->type()==QEvent::MouseMove)
        {
            auto me=dynamic_cast<QMouseEvent*>(event);
            move(me->globalPosition().toPoint()-pressPos);
            //globalPosition是鼠标在全局的位置,pressPos是鼠标相对于窗口左上角的位置,两者一减,就是窗口左上角在全局的位置
        }
        else
            return false;
    }
    else
        return QObject::eventFilter(watched,event);
}

};

3.事件和信号的区别

事件信号
与QObject的关系由具体对象进行处理由具体对象主动产生
对程序的影响改写事件处理函数可能导致程序行为发生改变信号是否存在对应的槽函数不会改变程序的行为
两者的联系一般而言,信号在具体的事件处理函数中产生

信号和事件是两个不同层面的东西,发出者不同,作用不同。

举报

相关推荐

0 条评论