Отображение QMessageBox из кода C, работающего в QThread - PullRequest
0 голосов
/ 04 января 2011

У меня есть основной (GUI) поток, который создает QThread.

В QThread я вызываю функцию C, которая должна отображать QMessageBox.До сих пор я просто использовал:

void notify(char *str)
{
  QMessageBox::information(0, "", QString(str));
}

в коде C ++ и вызывал его из кода C.Это работало нормально без потоков, но теперь с потоками я получаю ошибки, потому что невозможно вызвать функции GUI из другого потока.

Обычно это можно обойти, используя сигналы типа ответа на этот вопрос предлагает;однако я сомневаюсь, что могу сделать это из кода C.

Итак, как я могу заставить код C взаимодействовать с потоком GUI и сказать ему отображать QMessageBox?

Спасибо.

PS

Если возможно, я бы хотел сделать это, не касаясь кода C (на данный момент в заголовках кода C просто есть объявление extern void notify(char *), и, если возможно, яхотелось бы остаться на этом.

1 Ответ

3 голосов
/ 04 января 2011

Предполагая, что у вас есть производный класс QWidget или QMainWindow для вашего GUI, вы можете добавить к нему следующее:

class MyWidget : public QWidget
{
    Q_OBJECT;
public:    
    MyWidget()
    {
        connect(this, SIGNAL(notify_sig(QString)),
                this, SLOT(notify_slot(QString)),
                Qt::QueuedConnection);
    }

    void notify(QString str)
    {
        emit notify_sig(str);
    }

    signals:
        void notify_sig(QString str);

    slots:
        void notify_slot(QString str)
        {
            QMessageBox::information(0, "", str);
        }
};

Здесь у вас есть открытая функция notify(), которая является членом класса виджетов. Вызов MyWidget::notify() приводит к отправке сигнала себе через соединение с очередями (что приведет к вызову слота в потоке GUI). Теперь вызову C notify() просто нужно вызвать функцию notify() виджета / окна. Это может быть сложно, поскольку у вас нет указателя на виджет, доступный в функции C notify().

Обычно интерфейс C позволяет пользователю передавать значение void* и затем возвращает это значение с помощью вызова notify. Это позволит вам передать указатель на MyWidget при вызове функции C и затем привести его обратно к MyWidget в реализации notify().

MyWidget* wid = ...;
C_function(arg1, ..., wid);

//...

void notify(char* str, void* userdata)
{
    MyWidget* wid = static_cast<MyWidget*>(userdata);
    wid->notify(QString(str));
}

Если вы не можете изменить интерфейс C, вам может понадобиться какой-то глобальный способ получения указателя на виджет / окно.

Обратите внимание, что я не тестировал ни один из этого кода, и может быть более простой способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...