Создание собственного сообщения / события с помощью Qt - PullRequest
4 голосов
/ 19 мая 2011

У меня есть поток RPC, который перезванивает мне из этого потока. Мне нужно как-то сообщить Qt, что он должен сделать вызов функции из основного потока. В прямой Windows я мог бы сделать это, используя пользовательское сообщение, а затем отправив это сообщение в очередь сообщений, например, я мог бы создать сообщение WM_CALLFUNCTION и передать указатель функции через wParam, а параметр (указатель класса) через lParam.

Кто-нибудь знает, как я могу сделать это с Qt? Я сталкивался с QCustomEvent, но понятия не имею, как его использовать или как его обработать. Любая помощь будет принята с благодарностью!

Edit:

В конце концов я выбрал QMetaObject :: invokeMethod , который отлично работает.

Ответы [ 2 ]

7 голосов
/ 20 мая 2011

Использование пользовательских событий обычно включает в себя создание собственного подкласса QEvent, переопределение customEvent () в классе QObject, который будет получать событие (часто класс основного окна), и некоторый код, который «отправляет» событие из вашего потока в получатель.

Мне нравится реализовывать код сообщения о событии как метод класса получателя. Таким образом, вызывающая сторона должна знать только об объекте recevier, а не о специфике 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 служат для демонстрации того, как вы можете передавать некоторые данные в вашем мероприятии. Они не должны быть 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);

где, только для нашего примера, 1 и 2 могут быть любыми целочисленными данными.

5 голосов
/ 19 мая 2011

В Qt 3 обычным способом связи с потоком GUI из потока, не являющегося GUI, было отправка пользовательского события в QObject в потоке GUI.В Qt 4 это все еще работает и может быть обобщено на случай, когда одному потоку необходимо связаться с любым другим потоком, имеющим цикл обработки событий.

Чтобы упростить программирование, Qt 4 также позволяет вам устанавливать сигнал:слот соединения между потоками.За кулисами эти соединения реализуются с использованием события.Если сигнал имеет какие-либо параметры, они также сохраняются в событии.Как и ранее, если отправитель и получатель живут в одном потоке, Qt выполняет прямой вызов функции.

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

...