C++ 从另一个std::thread调用Qt对象方法
我有一个简单的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
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_对象宏中使用。