4

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

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

编辑:

最后我选择了QMetaObject::invokeMethod,它工作得很好。

4

2 回答 2

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他们不必是ints。

// 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);

其中,仅用于我们的示例,1并且2可以是任何整数数据。

于 2011-05-20T03:25:41.060 回答
5

在 Qt 3 中,从非 GUI 线程与 GUI 线程进行通信的常用方法是将自定义事件发布到 GUI 线程中的 QObject。在 Qt 4 中,这仍然有效,并且可以推广到一个线程需要与具有事件循环的任何其他线程通信的情况。

为了简化编程,Qt 4 还允许您建立跨线程的信号槽连接。在幕后,这些连接是使用事件实现的。如果信号有任何参数,这些也存储在事件中。和以前一样,如果发送者和接收者在同一个线程中,Qt 会直接调用函数。

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

于 2011-05-19T16:24:31.020 回答