从QThread中运行的C代码显示QMessageBox

时间:2011-01-03 23:16:21

标签: c++ c multithreading qt

我有一个创建QThread的主(GUI)线程。

在QThread中,我正在调用一个需要显示QMessageBox的C函数。到目前为止,我只是使用:

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

在C ++代码中并从C代码中调用它。这没有线程工作正常,但现在使用线程我收到错误,因为无法从另一个线程调用GUI函数。

通常情况下,这可以通过使用this question建议的回答等信号来规避;但是,我怀疑我可以用C代码做到这一点。

那么,如何让C代码与GUI线程通信并告诉它显示QMessageBox?

感谢。

P.S。

如果可能的话,我想在不触及C代码的情况下这样做(截至目前,在C代码的标题中只有一个extern void notify(char *)声明,如果可能的话,我希望它留在这一点。

1 个答案:

答案 0 :(得分:3)

假设您的GUI有QWidgetQMainWindow派生类,您可以添加以下内容:

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(),它是widget类的成员。调用MyWidget::notify()会导致信号通过排队连接发送给自己(这将导致在GUI线程中调用插槽)。现在,C notify()调用只需要调用窗口小部件/窗口的notify()函数。这可能很棘手,因为您实际上没有指向C notify()函数中可用小部件的指针。

通常,C接口允许用户传入void*值,然后通过notify调用返回该值。这将允许您在调用C函数时将指针传递给MyWidget,然后将其强制转换回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接口,则可能需要使用某种全局方式来获取窗口小部件/窗口的指针。

请注意,我尚未测试任何此代码,并且可能有更简单的方法来执行此操作。