如何在Qt中使用线程向文本编辑器添加文本

时间:2015-07-01 20:19:43

标签: c++ multithreading qt

对于我在Qt工作的项目,我需要同时做几件事。其中一个事件是获取温度读数并在文本编辑框中显示该读数以及时间戳。在我写完的while循环完成之前,临时和时间戳不会显示。我知道while循环阻塞它所以我试图编写一个线程来显示时间和临时值,但是无法弄清楚如何从线程写入gui。

这是我启动线程和while循环的地方

QThread cThread;
timeTempObject cObject;

cObject.DoSetup(cThread);
cObject.moveToThread(&cThread);
cThread.start();

while(flowTime > 0)
{
    // set zero pin to be high while flowtime is more than 0
    digitalWrite(0,1);
    displayCurrentTime();

    // set second pin LED to flash according to dutyCycle
    digitalWrite(2,1);
    delay(onTime);
    // displayCurrentTime();
    ui->tempTimeNoHeatMode->append(temp);

    digitalWrite(2,0);
    delay(offTime);

    flowTime--;
}

noheatmode.h

namespace Ui {
class noheatmode;
}

class noheatmode : public QWidget
{
    Q_OBJECT

public:
    explicit noheatmode(QWidget *parent = 0);
    ~noheatmode();

private slots:
    void on_startButtonNoHeatMode_clicked();

    void on_noHeatModeBack_clicked();

public slots:
    void displayCurrentTime();

private:
    Ui::noheatmode *ui;
};

#endif // NOHEATMODE_H

线程的timetempobject.h

class timeTempObject : public QObject
{
    Q_OBJECT

public:
    explicit timeTempObject(QObject *parent = 0);
    void DoSetup(QThread &cThread);

public slots:
    void DoWork();
};

#endif // TIMETEMPOBJECT_H

timetempobject.cpp

timeTempObject::timeTempObject(QObject *parent) :
QObject(parent)
{
}

void timeTempObject::DoSetup(QThread &cThread)
{
    connect(&cThread,SIGNAL(started()),this,SLOT(DoWork()));
}

void timeTempObject::DoWork()
{
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(displayCurrentTime()));

    // delay set to space out time readings, can be adjusted
    timer->start(1500);

    // Gets the time
    QTime time = QTime::currentTime();

    // Converts to string with chosen format
    QString sTime = time.toString("hh:mm:ss:ms");

    // displays current time in text edit box
    Ui::noheatmode* noheatmode::ui->tempTimeNoHeatMode->append(sTime);
}

如何更改我的线程,以便它可以写入我的gui中的文本编辑器?

1 个答案:

答案 0 :(得分:2)

由于QTextEdit::append是一个广告位,因此很容易从其他广告位调用它:

void tempTimeObject::DoWork() {
  ...
  QMetaObject::invokeMethod(ui->tempTimeNoHeatMode, "append", 
                            Qt::QueuedConnection, Q_ARG(QString, temp));
  ...
}

如果你希望执行任意代码,那么归结为"如何在给定线程中执行仿函数",线程是主线程。 this question的答案提供了多种方法。

Qt 5上最简单的方法是:

void tempTimeObject::DoWork() {
  ...
  {
    QObject signalSource;
    QObject::connect(&signalSource, &QObject::destroyed, qApp, [=](QObject *){
      ui->tempTimeNoHeatMode->append(text);
      ... // other GUI manipulations
    });
  } // here signalSource emits the signal and posts the functor to the GUI thread
  ...
}