H.Y Kim
H.Y Kim

Reputation: 13

QT-How to utilize QWidget with QThread?

I'm making some GUI through QT. I almost complete my work but I have a hard time dealing with Qthread. My goal is to measure the position of the motor (it moves) and display it on the Qtextbrowser while working another function in the main thread. When I wrote codes like below, people said I can't use QTextBrowser(Qwidget) directly in the thread, so I'm searching how to return location value to the main thread. Can you do me a favor? MDCE is a class in another header and the codes I attach are some parts of my first code.

void MotorPort::StartThread(MDCE* com, QTextBrowser* browser)
{

    thread1 = QThread::create(std::bind(&MotorPort::MeasureLocation,this,com,browser));
    thread1 -> start();
}

void MotorPort::MeasureLocation(MDCE* com, QTextBrowser* browser)
{
    double location;
    while(1)
    {
        location = CurrentLocation(com); \\return current position value
        browser->setText(QString::number(location));
        if (QThread::currentThread()->isInterruptionRequested()) return ;
    }
}

void MotorPort::stopMeasure()
{
    thread1->requestInterruption();
    if (!thread1->wait(3000))
    {
        thread1->terminate();
        thread1->wait();
    }
    thread1 = nullptr;
}

Upvotes: 0

Views: 876

Answers (1)

G.M.
G.M.

Reputation: 12929

You should use the Qt signal/slot mechanism for iter-thread notification such as this. Firstly change your MotorPort class definition to declare a signal location_changed...

class MotorPort: public QObject {
    Q_OBJECT;
signals:
    void location_changed(QString location);
    ...
}

Now, rather than MotorPort::MeasureLocation invoking QTextBrowser::setText directly it should emit the location_changed signal...

void MotorPort::MeasureLocation (MDCE *com, QTextBrowser *browser)
{
    while (true) {
        double location = CurrentLocation(com);

        /*
         * Emit signal to notify of location update.
         */
        emit location_changed(QString::number(location));
        if (QThread::currentThread()->isInterruptionRequested())
            return ;
    }
}

Finally, update MotorPort::StartThread to connect the signal to the browser's setText slot...

void MotorPort::StartThread (MDCE *com, QTextBrowser *browser)
{
    connect(this, &MotorPort::location_changed, browser, &QTextBrowser::setText);
    thread1 = QThread::create(std::bind(&MotorPort::MeasureLocation, this, com, browser));
    thread1->start();
}

Upvotes: 1

Related Questions