从QThread中运行的C代码显示QMessageBox [英] Display a QMessageBox from C code running in a QThread
问题描述
我有一个创建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的QWidget
或QMainWindow
派生类,则可以在其中添加以下内容:
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屋!