使用Qt创建自定义消息/事件

时间:2011-05-19 15:49:04

标签: c++ qt postmessage

我有一个从该线程回调给我的RPC线程。我需要以某种方式告知Qt它需要从主线程进行函数调用。在直接Windows中我可以通过使用自定义消息然后将该消息发布到消息队列来完成此操作,例如,我可以创建WM_CALLFUNCTION消息并通过wParam和参数(类)传递函数指针指针)通过lParam

有谁知道如何用Qt做到这一点?我遇到QCustomEvent,但我不知道如何使用它或如何处理它。任何帮助都将非常感激!

编辑:

最后,我选择QMetaObject::invokeMethod,效果很好。

2 个答案:

答案 0 :(得分:7)

使用自定义事件通常涉及创建自己的QEvent子类,覆盖将接收事件的QObject类中的customEvent()(通常是主窗口类)和一些将事件从您的线程“发布”到接收器的代码。

我喜欢将事件发布代码实现为接收器类的方法。这样,调用者只需知道接收对象而不是任何“Qt”细节。调用者将调用此方法,然后基本上将消息发布给自己。希望下面的代码能让它更清晰。

// MainWindow.h
...
// Define your custom event identifier
const QEvent::Type MY_CUSTOM_EVENT = static_cast<QEvent::Type>(QEvent::User + 1);

// Define your custom event subclass
class MyCustomEvent : public QEvent
{
    public:
        MyCustomEvent(const int customData1, const int customData2):
            QEvent(MY_CUSTOM_EVENT),
            m_customData1(customData1),
            m_customData2(customData2)
        {
        }

        int getCustomData1() const
        {
            return m_customData1;
        }

        int getCustomData2() const
        {
            return m_customData2;
        }

    private:
        int m_customData1;
        int m_customData2;
};

public:
void postMyCustomEvent(const int customData1, const int customData2);
....
protected:
void customEvent(QEvent *event); // This overrides QObject::customEvent()
...
private:
void handleMyCustomEvent(const MyCustomEvent *event);

customData1customData2用于演示如何在活动中传递一些数据。它们不一定是int

// MainWindow.cpp
...
void MainWindow::postMyCustomEvent(const int customData1, const int customData2)
{   
    // This method (postMyCustomEvent) can be called from any thread

    QApplication::postEvent(this, new MyCustomEvent(customData1, customData2));   
}

void MainWindow::customEvent(QEvent * event)
{
    // When we get here, we've crossed the thread boundary and are now
    // executing in the Qt object's thread

    if(event->type() == MY_CUSTOM_EVENT)
    {
        handleMyCustomEvent(static_cast<MyCustomEvent *>(event));
    }

    // use more else ifs to handle other custom events
}

void MainWindow::handleMyCustomEvent(const MyCustomEvent *event)
{
    // Now you can safely do something with your Qt objects.
    // Access your custom data using event->getCustomData1() etc.
}

我希望我没有遗漏任何东西。有了这个,其他一些线程中的代码只需要一个指向MainWindow对象的指针(让我们称之为mainWindow)并调用

mainWindow->postMyCustomEvent(1,2);

其中,仅我们的示例,12可以是任何整数数据。

答案 1 :(得分:5)

  

在Qt 3中,通常的沟通方式   使用来自非GUI的GUI线程   线程是通过发布自定义事件   到GUI线程中的QObject。在Qt   4,这仍然有效,可以   推广到一个案例   线程需要与任何进行通信   其他具有事件循环的线程。

     

为了简化编程,Qt 4也允许   你建立信号 - 槽   跨线程的连接。在...后面   场景,这些联系是   使用事件实现。如果   信号有任何参数,这些都是   也存储在事件中。喜欢   以前,如果是发件人和收件人   生活在同一个线程中,Qt制作了一个   直接函数调用。

- http://doc.qt.nokia.com/qq/qq14-threading.html#signalslotconnectionsacrossthreads