Qt中的事件(3)- 自定义事件


1、自定义事件步骤

有时为了开发需要,我们希望自定义事件来完成某种目的。实现自定义事件的步骤如下:

  • 继承QEvent。
  • 定义事件类型(取值在QEvent::User和QEvent::MaxUser之间,建议使用registerEventType()函数自动创建一个全局唯一一个的事件类型,防止重复)
  • 使用sendEvent()或postEvent()发送事件。
  • 需要在自定义类中重写QObject::event()方法处理自定义事件。

2、自定义事件类

自定义的事件类代码如下:
头文件

// -------------------------- 自定义事件 --------------------------------
class CustomerEvent : public QEvent
{
public:
    CustomerEvent(QString valueString = "");
    ~CustomerEvent();

    static Type eventType();
    QString getValueString(void);

private:
    static Type m_EventType;
    QString m_String;
};

源文件

QEvent::Type CustomerEvent::m_EventType = QEvent::None;

CustomerEvent::CustomerEvent(QString valueString) : QEvent(eventType())
{
    m_String = valueString;
}

CustomerEvent::~CustomerEvent()
{

}

QEvent::Type CustomerEvent::eventType()
{
    // 创建事件Type
    if (m_EventType == QEvent::None)
        m_EventType = (QEvent::Type)QEvent::registerEventType();

    return m_EventType;
}

QString CustomerEvent::getValueString(void)
{
    return m_String;
}

这里使用了CustomerEvent::eventType()函数为事件创建了类型。

3、发送事件

发送事件有两种方法,一种是使用sendEvent()函数,一种是使用postEvent()函数。

(1)sendEvent方法

sendEvent()方法是阻塞的,它发送个对象事件,等待接受对象处理结束后返回。函数原型如下:
static bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event);
参数: receiver为接受事件的对象, event为传递的事件指针
返回值:若事件被处理返回true, 否则返回false。
说明: 这个函数需要手动去释放事件的内存。

(2)postEvent方法

postEvent()为异步的方法,它向事件队列中登记一个指定接收者的事件,然后返回。函数原型如下:
static void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority);
参数:receiver为接受事件的对象, event为传递的事件指针, priority为优先级
说明:这个函数不需要手动去释放事件的内存,有Qt框架自动释放。

使用PostEvent和SendEvent的例子如下:
头文件

class Widget : public QWidget
{
    Q_OBJECT

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

protected:
    virtual bool event(QEvent *event) override;
};

这里定义了一个Widget, 其中event()函数后面处理自定义事件时会用到。

源文件

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    // 创建按钮并布局
    QPushButton *button = new QPushButton("CreateEvent", this);
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(button);
    this->setGeometry(100, 100, 800, 600);

    // 建立连接, 发送信号
    QObject::connect(button, &QPushButton::clicked, [=](void)->void{
        // 使用PostEvent方式发送
        CustomerEvent *customerEvent = new CustomerEvent("PostCustomerEvent");
        QCoreApplication::postEvent(this, customerEvent);

        // 使用SendEvent方式发送
        CustomerEvent *sendCustomerEvent = new CustomerEvent("SendCustomerEvent");
        bool result = QCoreApplication::sendEvent(this, sendCustomerEvent);
        qDebug() << "The Dispose Result Is " << result;
        delete sendCustomerEvent;
    });
}

Widget::~Widget()
{

}

这里创建了一个按钮,当按钮按下时发送自定义的事件。

4、事件处理

通过重写QObject::event()的方式处理自定义事件。代码如下:

bool Widget::event(QEvent *event)
{
    if (event->type() == CustomerEvent::eventType())
    {
        CustomerEvent *customerEvent = dynamic_cast<CustomerEvent*>(event);
        qDebug() << customerEvent->getValueString();
        return true;
    }
    return QWidget::event(event);
}

函数的返回true表示已经处理了此事件,否则返回false。

整体程序的运行结果为:
“SendCustomerEvent”
The Dispose Result Is true
“PostCustomerEvent”
可见,函数先处理了sendEvent()函数的事件, 等事件循环运行时分发给当前对象后处理。

  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值