从QThread中运行的C代码显示QMessageBox [英] Display a QMessageBox from C code running in a QThread

查看:232
本文介绍了从QThread中运行的C代码显示QMessageBox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the main (GUI) thread which creates a QThread.

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

In the QThread, I am calling a C function that needs to display a QMessageBox. So far, I simply used:

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

在C ++代码中

并从C代码中调用它.在没有线程的情况下,这种方法可以正常工作,但是现在在线程中,我遇到了错误,因为一个人不能从另一个线程调用GUI函数.

in the C++ code and called it from the C code. This worked fine without threads, but now with threads I am getting errors, because one cannot call the GUI functions from another thread.

通常,可以通过使用诸如此问题的答案之类的信号来避免这种情况建议;但是,我怀疑我可以从C代码中做到这一点.

Usually, this could be circumvented by using signals like the answer to this question suggests; however, I doubt I can do this from the C code.

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

So, how can I make the C code communicate with the GUI thread and tell it to display a QMessageBox?

谢谢.

P.S.

如果可能的话,我希望在不触碰C代码的情况下进行此操作(到目前为止,C代码的标头中仅包含一个extern void notify(char *)声明,如果可能的话,我希望它保持不变.

If possible, I'd like to do this without touching the C code (as of now, there is simply an extern void notify(char *) declaration in the C code's headers, and if possible I'd like it to stay at that.

推荐答案

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

Assuming you have a QWidget or QMainWindow derived class for your GUI, you could add the following to it:

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()函数中可用的小部件的指针.

Here you have a public function notify() that is a member of the widget class. Calling MyWidget::notify() results in a signal being sent to itself through a queued connection (which will result in the slot being called in the GUI thread). Now the C notify() call just needs to call the widget/window's notify() function. This can be tricky since you don't really have a pointer to the widget available in the C notify() function.

通常,C接口将允许用户传递void*值,然后通过notify调用返回该值.这将允许您在调用C函数时将指针传递给MyWidget,然后在notify()实现中将其强制转换回MyWidget.

Normally, the C interface would allow the user to pass a void* value in and would then return that value with the notify call. This would allow you to pass in the pointer to MyWidget when the C function is called and then cast it back to MyWidget in the notify() implementation.

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

//...

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

如果无法更改C接口,则可能需要使用某种全局方式来获取小部件/窗口的指针.

If you can't change the C interface, you may need to use some kind of global way of getting the widget/window's pointer.

请注意,我尚未测试任何这些代码,并且可能有更简单的方法来实现此目的.

Note that I have not tested any of this code and there may be an easier way to do this.

这篇关于从QThread中运行的C代码显示QMessageBox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆