2011-05-19 666 views
4

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

有没有人有一个想法,我怎么可以用Qt做到这一点?我碰到过QCustomEvent,但我不知道如何使用它或如何处理它。任何帮助将非常感激!

编辑:

在我QMetaObject::invokeMethod去年底,其完美的作品。

+0

而不是QCustomeEvent,为什么不使用信号/插槽机制? – Arlen 2011-05-19 15:58:38

+0

以什么方式......我将如何从线程B调用线程A以执行函数...? – Goz 2011-05-19 16:10:32

+1

Qt信号/插槽机制是线程安全的,可以跨线程使用。如果你不知道如何查找信号/插槽教程。 – Arlen 2011-05-19 16:23:32

回答

5

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

+0

干杯!但是,您究竟如何在线程间建立信号插槽连接? – Goz 2011-05-19 16:50:32

+0

对于一个...我是否需要从Qt线程运行来执行此操作?因为我需要回调的线程是非QT线程... – Goz 2011-05-19 16:53:03

+0

GUI必须在主线程中运行。如果你没有处理小部件,那么你需要继承QObject并实现你的信号/插槽。 – Arlen 2011-05-19 17:13:50

6

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

我喜欢将事件发布代码作为接收者类的一种方法实现。这样,调用者只需知道接收对象而不是任何“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 s。

// 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可以是任意整数数据。

+0

'QApplication :: postEvent(this,new StatisticEvent(p,dltotal,dlnow,uptotal,upnow));'我得到错误,'/home/phobos/Programming/FyreDL/src/cmnroutines.cpp:1241: 29:错误:无法初始化类型为'QObject *'的参数,类型为'GekkoFyre :: StatisticEvent *'QApplication :: postEvent(this,new StatisticEvent(p,dltotal,dlnow,uptotal,upnow));''我不知道该怎么做。有人可以帮忙吗?这将不胜感激。 – 2016-10-22 22:57:00