我有简单的Qt表单,代表我的应用程序的主窗口。它有方法:
void gui_popup::on_pushButton_clicked()
{
QString text = ui->MainText->toPlainText();
text = "1\n" + text;
ui->MainText->setText(text);
}
我也有一些代码,在另一个线程中运行,创建如下:
std:thread* core_thread = new thread(&Init); //void Init()...
然后,在某些时刻或来自 std :: thread 的条件代码需要调用 gui_popup :: on_pushButton_clicked()。我试着这样做:
void test_callback(void* object_ptr)
{
auto this_object = (gui_popup*)object_ptr;
this_object->on_pushButton_clicked();
}
在std :: thread代码中,我正在保存 test_callback 指针和 gui_popup 对象指针。但是当它开始调用 on_pushButton_clicked()程序停止时出现分段错误错误。这段代码适用于其他一些简单的类,但不适用于QtObject。我做错了什么?
更新 我用这种方式解决了它:
void test_callback(void* object_ptr)
{
QMetaObject qtmo;
qtmo.invokeMethod((gui_popup*)object_ptr, "on_pushButton_clicked");
}
当然,它比使用QThread,发出信号和所有其他建议的解决方案复杂得多。不过感谢大家的帮助。
答案 0 :(得分:3)
我通常会这样解决:
class Foo : public QObject
{
Q_OBJECT
Foo()
{
// connect to own signal to own slot and hence "translate" it
connect(this, SIGNAL(some_signal(QString)),
this, SLOT(some_slot(QString)));
}
signals:
void some_signal(QString s);
protected slots:
void some_slot(QString s)
{
// do something with your gui
}
public:
void callback_proxy(std::string s)
{
emit some_signal(QString::fromUtf8(m_string.c_str()));
}
};
然后胎面不需要了解QT:
void thread_run_function(Foo* foo)
{
foo->callback_proxy("Hello from Thread!");
}
据我所知,这是保存,因为connect(信号,插槽)确实有一个额外的默认参数(Qt::ConnectionType
类型,默认为Qt::AutoConnection
)。这告诉QT如果它们来自外部线程,则将信号分配到qt主事件循环中。请注意,使用此连接类型必须使qt决定运行时是调度信号还是立即调用插槽。
HtH Martin
编辑:有关默认参数的更多信息,此链接作为参考: 见http://doc.qt.io/qt-5/qt.html#ConnectionType-enum