How to Alter Qt Widgets in Winapi Threads

How can I change GUI from std::thread?

As you asked for the demo with QThread, in the comments, then here it is.

As GUI, I have a mainwindow with two simple buttons and I want to show, hide the big buttons with a QThread (instead of just the slot clicked) I emit an intermediate signal from the clicked to hide/show the button.

The role of the QThreadis only to emit the signal to sigShowHide with argument trueor false.

The main UI thread treats this signal by showing or hiding the button by calling the slot onShowHideButtonThreaded which reacts to the signal sigShowHide

Sample Image

Here are the code files:

mainwindows.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

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

signals:

void sigShowHide(bool);

public slots:
void onShowHideButtonThreaded(bool);
void onButton1Click();

private:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::onButton1Click);
QObject::connect(this,&MainWindow::sigShowHide, this, &MainWindow::onShowHideButtonThreaded);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::onShowHideButtonThreaded(bool a)
{
qDebug() << " the main thread id = " << QThread::currentThread() << "set the visibility ";
ui->pushButton_2->setVisible(a);
}

void MainWindow::onButton1Click()
{
qDebug()<< "clicked";
qDebug() << " the main thread id = " << QThread::currentThread();
QThread* l_thread = QThread::create([&]()
{
qDebug() << "Running Thread " << QThread::currentThreadId() << " to emit signal only ";
emit sigShowHide( !this->ui->pushButton_2->isVisible());
});
l_thread->start();
}

`

The main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}

An example of execution is :

the main thread id = QThread(0x116ee18)
Running Thread 0x1ed8 to emit signal only
the main thread id = QThread(0x116ee18) set the visibility

QT-How to utilize QWidget with QThread?

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();
}

Qt C++ Displaying images outside the GUI thread (Boost thread)

I solved using signal/slot: the "non-GUI" thread emits a signal instead of displaying the images and the called slot paints the QLabel inside the GUI thread!

update QLineEdit value every n seconds

You should use a QTimer, assuming you're allowed to (even if you were allowed to use threads). Doing any sort of blocking on the UI thread will not work, it needs to be released for event processing to work, and reacting to clicks needs event processing.

The Timers page has a bit more info and examples of how to use it. The idea here would be to create a slot that simply does:

ui->editElement->setText(QString::number(getVariableValue()));

and a repeating timer connected to that slot.

(This assumes that getVariableValue() is properly synchronised and does indeed see the updated value from that other thread.)



Related Topics



Leave a reply



Submit