Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从另一个std::thread调用Qt对象方法_C++_Multithreading_Qt_C++11 - Fatal编程技术网

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

C++ 从另一个std::thread调用Qt对象方法,c++,multithreading,qt,c++11,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

我有一个简单的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()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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()));
     }
};
然后,在某个时刻,来自std::thread的条件代码需要调用gui\u popup::on\u button\u clicked()。我试着这样做:

std:thread* core_thread = new thread(&Init); //void Init()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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()));
     }
};
在std::thread代码中,我保存了test\u回调指针和gui\u弹出对象指针。但当它开始调用_按钮时,_clicked()程序因分段错误而停止。此代码适用于其他一些简单类,但不适用于QtObject。我做错了什么

更新: 我是这样解决的:

void test_callback(void* object_ptr)
{
    QMetaObject qtmo;
    qtmo.invokeMethod((gui_popup*)object_ptr, "on_pushButton_clicked");
}

当然,它比使用QThread、发出信号和所有其他建议的解决方案要复杂得多。不过,谢谢大家的帮助。

我通常会这样解决:

std:thread* core_thread = new thread(&Init); //void Init()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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
type,默认为
Qt::AutoConnection
)。这会告诉QT如果信号来自外部线程,则将其分派到QT主事件循环中。请注意,使用这种连接类型基本上会使qt在运行时决定是分派信号还是立即调用插槽

马丁

编辑:有关默认参数和此链接作为参考的更多信息:
请参见

我通常这样解决它:

std:thread* core_thread = new thread(&Init); //void Init()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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
type,默认为
Qt::AutoConnection
)。这会告诉QT如果信号来自外部线程,则将其分派到QT主事件循环中。请注意,使用这种连接类型基本上会使qt在运行时决定是分派信号还是立即调用插槽

马丁

编辑:有关默认参数和此链接作为参考的更多信息:
请参见

我通常这样解决它:

std:thread* core_thread = new thread(&Init); //void Init()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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
type,默认为
Qt::AutoConnection
)。这会告诉QT如果信号来自外部线程,则将其分派到QT主事件循环中。请注意,使用这种连接类型基本上会使qt在运行时决定是分派信号还是立即调用插槽

马丁

编辑:有关默认参数和此链接作为参考的更多信息:
请参见

我通常这样解决它:

std:thread* core_thread = new thread(&Init); //void Init()...
void test_callback(void* object_ptr)
{
    auto this_object = (gui_popup*)object_ptr;
    this_object->on_pushButton_clicked();
}
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
type,默认为
Qt::AutoConnection
)。这会告诉QT如果信号来自外部线程,则将其分派到QT主事件循环中。请注意,使用这种连接类型基本上会使qt在运行时决定是分派信号还是立即调用插槽

马丁

编辑:有关默认参数和此链接作为参考的更多信息:

请参见

您需要发出信号,而不是使用QThread直接调用函数。使用信号和插槽,您可以轻松安全地执行此操作。是否存在不能使用Qthread+worker QObject子类的选项?@Bћ能否提供如何为某个插槽发出信号的示例?@AlekDepler首先在标题中定义信号,然后
emit clickbutdown()并使用connect语句捕获。别忘了伙计们,我们只能在QObject子类中使用Qt信号和插槽,并且只能在Q_OBJECT宏中使用。您需要发出信号,而不是直接使用QThread调用函数。使用信号和插槽可以非常轻松安全地完成此操作。是否存在不能使用Qthread+worker QObject子类的选项?@Bћ能否提供如何为某个插槽发出信号的示例?@AlekDepler首先在标题中定义信号,然后
emit clickbutdown()并使用connect语句捕获。别忘了伙计们,我们只能在QObject子类中使用Qt信号和插槽,并且只能在Q_OBJECT宏中使用。您需要发出信号,而不是直接使用QThread调用函数。使用信号和插槽可以非常轻松安全地完成此操作。是否存在不能使用Qthread+worker QObject子类的选项?@Bћ能否提供如何为某个插槽发出信号的示例?@AlekDepler首先在标题中定义信号,然后
emit clickbutdown()并使用connect语句捕获。别忘了伙计们,我们只能在QObject子类中使用Qt信号和插槽,并且只能在Q_OBJECT宏中使用。您需要发出信号,而不是直接使用QThread调用函数。使用信号和插槽可以非常轻松安全地完成此操作。是否存在不能使用Qthread+worker QObject子类的选项?@Bћ能否提供如何为某个插槽发出信号的示例?@AlekDepler首先在标题中定义信号,然后
emit clickbutdown()并通过connect语句捕捉到它。别忘了伙计们,我们只能在QObject子类中使用Qt信号和插槽,并且只能在Q_对象宏中使用。