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

发布于 2024-11-08 00:15:38 字数 446 浏览 0 评论 0原文

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

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

编辑:

最后我选择了 QMetaObject::invokeMethod工作完美。

I have an RPC thread that is calling back to me from that thread. I need to somehow inform Qt that it needs to make a function call from the main thread. In straight Windows I could do this by using a custom message and then posting that message to the message queue, e.g., I could create a WM_CALLFUNCTION message and pass the function pointer through wParam and the parameter (class pointer) through lParam.

Has anyone an idea how I could do this with Qt? I've come across QCustomEvent but I have no idea how to use it or how to process it. Any help would be hugely appreciated!

Edit:

In the end I went with QMetaObject::invokeMethod which works perfectly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

坠似风落 2024-11-15 00:15:38

使用自定义事件通常涉及创建您自己的 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);

where,仅对于我们的示例来说,< code>1 和 2 可以是任何整数数据。

Using custom events generally involves creating your own QEvent subclass, overriding customEvent() in the QObject class that will receive the event (often the main window class) and some code that "posts" the event from your thread to the receiver.

I like to implement the event posting code as a method of the receiver class. That way, the caller only has to know about the recevier object and not any of the "Qt" specifics. The caller will invoke this method which will then essentially post a message to itself. Hopefully the code below will make it clearer.

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

The customData1 and customData2 are there to demonstrate how you might pass some data along in your event. They don't have to be 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.
}

I hope I didn't leave anything out. With this in place, code in some other thread just needs to get a pointer to a MainWindow object (let's call it mainWindow) and call

mainWindow->postMyCustomEvent(1,2);

where, just for our example, 1 and 2 can be any integer data.

风苍溪 2024-11-15 00:15:38

在Qt 3中,通常的通信方式
与来自非 GUI 的 GUI 线程
线程是通过发布自定义事件
到 GUI 线程中的 QObject。在Qt中
4、这仍然有效并且可以
推广到以下情况:
线程需要与任何
具有事件循环的其他线程。

为了简化编程,Qt 4 还允许
你建立signal--slot
跨线程的连接。后面的
场景,这些连接是
使用事件实现。如果
信号有任何参数,这些是
也存储在事件中。喜欢
之前,如果发送者和接收者
住在同一个线程中,Qt 做了一个
直接函数调用。

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

In Qt 3, the usual way to communicate
with the GUI thread from a non-GUI
thread was by posting a custom event
to a QObject in the GUI thread. In Qt
4, this still works and can be
generalized to the case where one
thread needs to communicate with any
other thread that has an event loop.

To ease programming, Qt 4 also allows
you to establish signal--slot
connections across threads. Behind the
scenes, these connections are
implemented using an event. If the
signal has any parameters, these are
also stored in the event. Like
previously, if the sender and receiver
live in the same thread, Qt makes a
direct function call.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文