17

我想从 Qt 中的 C++ 线程 (std::thread) 发出信号。

我该怎么做?

4

4 回答 4

13

QThread您绝对可以从线程( ,std::thread甚至boost::thread)发出信号。只有你必须小心你的连接函数的第五个参数(Qt::ConnectionType):

If Qt::DirectConnection:当信号发出时,立即(从当前线程)调用槽。If Qt::QueuedConnection:当控制返回到接收者线程的事件循环时调用该槽。插槽在接收者的线程中执行。

有关更多选项,请参阅ConnectionType-enum

问题不在于您从哪个线程发出信号,而更多的是从哪个线程调用插槽。例如,我认为QLabel::setText必须从QLabel的所有者线程(很可能是主线程)执行。因此,如果您从线程发出连接到 a 的信号QLabel,则setText必须使用Qt::AutoConnection,Qt::QueuedConnection或来完成连接Qt::BlockingQueuedConnection

于 2014-07-27T15:34:03.797 回答
4

std::thread通常,您可能不应该不小心从 -created 线程发出 Qt 信号。请参阅Jpo38 的回答:连接类型很重要,等等...

如果线程正在运行一些 Qt 事件循环,您可能可以。查看线程和 QObject

有一个(可能特定于 Unix 的)解决方法,与使用 Qt 的 Unix 信号做同样的事情:使用从你std::thread到主线程的管道。

但是,正如Joachim Pileborg所评论的,您应该制作自己的QThread。它是最简单的,也可能是最短的(就源代码而言),您只需复制并粘贴一些现有示例并根据您的需要进行调整。

请注意,AFAIK 只有主线程应该执行 Qt GUI 操作。您不应该在主线程之外使用任何 QWidget(等等)!(顺便说一句,GTK 有同样的限制,至少在 Linux 上:只有主线程应该使用X Windows 系统协议

于 2014-07-27T15:19:18.057 回答
1

如果您保留指向 QObject 的指针,则可以使用QMetaObject::invokeMethod成员之一http://qt-project.org/doc/qt-5/qmetaobject.html#invokeMethod

可能您将不得不使用Qt::QueuedConnection,因此您的信号将在正确的线程(而不是您的 std::thread)上被调用。请记住,您的信号不会立即被调用。

于 2014-07-28T08:30:30.443 回答
0
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();
}

于 2019-03-21T09:48:26.027 回答