4

そのスレッドからコールバックしている RPC スレッドがあります。メインスレッドから関数呼び出しを行う必要があることを Qt に通知する必要があります。まっすぐなWindows では、カスタム メッセージを使用して、そのメッセージをメッセージ キューに投稿することでこれを行うことができWM_CALLFUNCTIONます。wParamlParam

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

customData1とはcustomData2、イベントでデータを渡す方法を示すためにあります。sである必要はありません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);

ここで、例として、1and2は任意の整数データにすることができます。

于 2011-05-20T03:25:41.060 に答える
5

Qt 3 では、非 GUI スレッドから GUI スレッドと通信する通常の方法は、カスタム イベントを GUI スレッドの QObject に投稿することでした。Qt 4 でもこれは機能し、1 つのスレッドがイベント ループを持つ他のスレッドと通信する必要がある場合に一般化できます。

プログラミングを容易にするために、Qt 4 ではスレッド間でシグナルとスロットの接続を確立することもできます。バックグラウンドで、これらの接続はイベントを使用して実装されます。信号にパラメータがある場合、これらもイベントに保存されます。以前と同様に、送信者と受信者が同じスレッドに存在する場合、Qt は直接関数呼び出しを行います。

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

于 2011-05-19T16:24:31.020 に答える