我想从C++线��(std::thread)中在Qt中发出一个信号。
我该怎么做?
我想从C++线��(std::thread)中在Qt中发出一个信号。
我该怎么做?
您绝对可以从线程(QThread
,std::thread
或甚至是boost::thread
)发出信号。只需注意连接函数的第五个参数(Qt::ConnectionType
):
如果使用 Qt::DirectConnection
: 当信号被发射时,槽会立即(从当前线程)被调用。
如果使用 Qt::QueuedConnection
: 当控制返回接收者线程的事件循环时,槽将被调用。该槽在接收者线程中执行。
有关更多选项,请参见ConnectionType-enum 。
问题并非真正由哪个线程发出信号,而是由哪个线程调用槽。例如,我认为QLabel :: setText
必须在QLabel
的所有者线程(最可能是主线程)中执行。因此,如果您从线程发出连接到QLabel
的setText
的信号,则必须使用Qt::AutoConnection
,Qt::QueuedConnection
或Qt::BlockingQueuedConnection
进行连接。
std :: thread
创建的线程中发出Qt信号而不加注意。请参见Jpo38的回答:连接类型很重要等等...
如果线程正在运行某些Qt事件循环,则可能可以。请参见线程和QObject
有一个(可能是Unix特定的)解决方法,与使用Qt处理Unix信号相同:从std :: thread
到主线程使用管道。
但是,正如Joachim Pileborg所评论的那样,您应该制作自己的QThread。它是最简单的,也可能是最短的(以源代码为单位),您只需要复制并粘贴一些现有的示例并根据需要进行调整。
请注意,据我所知,只有主线程应该进行Qt GUI操作。您不应在主线程之外使用任何QWidget(等...)! (顺便说一句,GTK有相同的限制,至少在Linux上:只有主线程才应该使用X Windows系统协议)
class MainForm : public QMainWindow
{
Q_OBJECT
public:
explicit MainForm(QWidget *parent = nullptr);
virtual ~MainForm();
private:
signals:
void signalSendButtonEnable(bool);
private slots:
void singalReceiveButtonEnable(bool);
};
MainForm::MainForm(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainForm), status_{false}, io_context_{}, timer_{io_context_}
{
ui->setupUi(this);
// bind SIGNAL & SLOT
connect(this, SIGNAL(signalSendButtonEnable(bool)), this, SLOT(singalReceiveButtonEnable(bool)));
}
MainForm::~MainForm()
{
delete ui;
}
void MainForm::singalReceiveButtonEnable(bool status){ //recv signal
qDebug() << "singalReceiveButtonEnable";
this->ui->btnConnect->setEnabled(status);
}
void MainForm::start(){
std::thread t([](){
sleep(20);
emit signalSendButtonEnable(true); //send signal
});
t.detach();
}