从另一个std :: thread调用Qt对象方法

时间:2014-12-01 14:32:49

标签: c++ multithreading qt c++11

我有简单的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,发出信号和所有其他建议的解决方案复杂得多。不过感谢大家的帮助。

1 个答案:

答案 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