Qt event事件发送

阻塞型事件发送

需要重写接收对象的event()事件处理函数

当事件发送后,将会立即进入event()事件处理函数进行事件处理

通过sendEvent()静态函数实现阻塞发送:

cpp 复制代码
bool QApplication::sendEvent ( QObject * receiver, QEvent * event ) ;
// receiver:接收对象, event :要发送的event类型(比如:鼠标双击)
//当有事件发送,将会调用receiver对象里的event()成员函数进行事件处理

sendEvent()函数是阻塞式的

new分配的事件对象被处理后,会由Qt内部自动摧毁

非阻塞型事件发送

需要重写接收对象的event()事件处理函数

当事件发送后立即返回,事件将会发送到事件队列中等待处理

通过postEvent()静态函数实现非阻塞发送:

cpp 复制代码
void QApplication::postEvent ( QObject * receiver, QEvent * event );

new分配的事件对象被处理后,会由Qt内部自动摧毁

自定义事件

Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展。在 Qt 中,你需要继承的类是 QEvent。

继承QEvent类,你需要提供一个QEvent::Type类型的参数,作为自定义事件的类型值。这里的QEvent::Type类型是QEvent里面定义的一个enum,因此,你是可以传递一个int的。重要的是,你的事件类型不能和已经存在的type值重复,否则会有不可预料的错误发生!因为系统会将你的事件当做系统事件进行派发和调用。在Qt中,系统将保留0 -- 999的值,也就是说,你的事件type要大于999. 具体来说,你的自定义事件的type要在QEvent::User和QEvent::MaxUser的范围之间。其中,QEvent::User值是1000,QEvent::MaxUser的值是65535。从这里知道,你最多可以定义64536个事件,相信这个数字已经足够大了!但是,即便如此,也只能保证用户自定义事件不能覆盖系统事件,并不能保证自定义事件之间不会被覆盖。为了解决这个问题,Qt提供了一个函数:registerEventType(),用于自定义事件的注册。该函数签名如下:

cpp 复制代码
static int QEvent::registerEventType ( int hint = -1 );

函数是static的,因此可以使用QEvent类直接调用。函数接受一个int值,其默认值为-1,返回值是创建的这个Type类型的值。如果hint是合法的,不会发生任何覆盖,则会返回这个值;如果hint不合法,系统会自动分配一个合法值并返回。因此,使用这个函数即可完成type值的指定。这个函数是线程安全的,因此不必另外添加同步。

h

https://zhuanlan.zhihu.com/p/630751403

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QEvent>
#include <QDebug>

class MyEvent: public QEvent
{
public:
    MyEvent(QEvent::Type type):QEvent(type)
    {
    }
    void setMessage(int message){
        m_message = message;
    }
    int GetMessage(){
        return m_message;
    }
    void SetStr(QString str){
        m_str = str;
    }
    QString GetStr(){
        return m_str;
    }

private:
    int m_message;
    QString m_str;
};

class TestLabel: public QWidget
{
public:
    TestLabel(QString str="111", QWidget* parent=0):QWidget(parent){
            label = new QLabel(str,this);
    }
protected:
    bool event(QEvent* ev)
    {
        MyEvent* myev = (MyEvent*)ev;
        if(myev->type() == QEvent::User){
            QString str = myev->GetStr();
            label->setText(str);
        }
        return true;
    }
private:
    QLabel* label;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected slots:
    void OnClicked(bool);
private:
    TestLabel* label1;
    TestLabel* label2;
    int number=0;
};

#endif // MAINWINDOW_H

.cpp

cpp 复制代码
#include "mainwindow.h"
#include <QApplication>
#include <QPushButton>
#include <iostream>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    label1 = new TestLabel("label1", this);
    label2 = new TestLabel("label2", this);
    label2->move(0,100);
    QPushButton* btn = new QPushButton("btn",this);
    btn->move(300,0);
    connect(btn,SIGNAL(clicked(bool)), this, SLOT(OnClicked(bool)));
}

MainWindow::~MainWindow()
{

}

void MainWindow::OnClicked(bool bl)
{
    QEvent::Type type = QEvent::User;
    MyEvent myev(type);
    myev.SetStr(QString::number(number++));
    qDebug()<<"type:"<<type;
    if(number%2 == 0){
        QApplication::sendEvent(label1, &myev);
    }
    else{
        QApplication::sendEvent(label2, &myev);
    }

}
相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能13 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G13 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt