how to call functions when the application is open
-
Hi I'm just learning about QT I'm getting 2 problems in the threading I'm using.
The first problem is when the condition isNointerface or isConnected = false and the problem appears.
QObject::startTimer: Timers cannot be started from another thread
The second problem is when calling the
PreWrite()
the function that is called makes the application error what should I do, here is my code
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); std::thread thread(&MainWindow::WorkerThread, this); thread.detach(); } void MainWindow::WorkerThread() { for(;;) { if (endThread) { break; } if (InitIso()) { if (isNoInterface) { isConnected = true; isNoInterface = false; } if (condi) { isConnected = true; ui->BtnOpen->setEnabled(true); while (state) { if (endThread){ return; } if (isWrite) { isWrite = false; ui->BtnOpen->setEnabled(false); if (PreWrite()) { qDebug() << "process succes"; } } else { QThread::msleep(1000); } } } else { if (isConnected) { ui->TbPath->clear(); ui->LblModel->setText(" "); ui->BtnOpen->setEnabled(false); } } } else{ // NO INTERFACE CONDITION if (!isNoInterface){ isNoInterface = true; ui->TbPath->clear(); ui->LblModel->setText(" "); ui->BtnOpen->setEnabled(false); } } } }
-
You cannot/must not use a secondary thread to do any UI operations in Qt.
Especially if you are learning about Qt I cannot imagine you need multithreading.
Nobody could possibly say anything about thePreWrite()
you call since you don't show its source and you do not say what error it causes. If you don't want it to error don't call it. -
@Blackzero said in how to call functions when the application is open:
void MainWindow::WorkerThread()
How to correctly create a worker thread using Qt is shown here
-
@Pl45m4 don't hand the kid the car keys, if he can barely walk in a straight line :P
@Blackzero DO NOT attempt anythings with threads, yet. There is no need for them in your case and you will hurt you and your project more when attempting to use them.
-
@Pl45m4 said in how to call functions when the application is open:
How to correctly create a worker thread using Qt is shown here
@J-Hilk Done. :))
-
@Blackzero No question is stupid, only through asking and questioning us and our surroundings can we truly learn! And I'm far away from upset, don't worry! Sticks and stones my break my bones, but words will never hurt me :)
It's just so, so, sooo many people new to programming or Qt in general fall in the pit as you currently are, I answered questions like this to the hundreds time, it feels like.
Usually people do not come from an asynchrony environment and struggle to implement/use Qt's Asynch natureYou didn't provide use with much information, about what you actually trying to do inside that Thread, the
QObject::startTimer: Timers cannot be started from another thread
triggered my QSerialPort/QModbus senses. If you explain that a bit more, we might actually be able to give good and cohesive advice -
@J-Hilk said in how to call functions when the application is open:
Tidak ada pertanyaan yang bodoh, hanya dengan bertanya dan mempertanyakan diri kita sendiri dan lingkungan sekitar kita dapat benar-benar belajar! Dan saya jauh dari kesal, jangan khawatir! Tongkat dan batu mematahkan tulangku, tapi kata-kata tidak akan pernah menyakitiku :)
I used to be familiar with python but I'm interested in learning C++ QT lately, I thought it was very easy and it's not, this makes me feel like the old days when I first learned programming, so many people laughed at me. but I have to keep learning, thanks for your support.
-
@J-Hilk said in how to call functions when the application is open:
You didn't provide use with much information, about what you actually trying to do inside that Thread, the QObject::startTimer: Timers cannot be started from another thread triggered my QSerialPort/QModbus senses. If you explain that a bit more, we might actually be able to give good and cohesive advice
sorry if my explanation is incomplete, it appeared when I installed this code
ui->BtnOpen->setEnabled(false); // or ui->BtnOpen->setEnabled(true);
but if the GUI boolean code is removed, the error does not appear
-
As explained above accessing UI from other threads is not supported and can also lead to crashes. Don't do that.
-
I still remain resolut in my opinion, that you should not use Qthreads at all, but for completeness:
In Qt, it is crucial to avoid modifying GUI elements directly from a different thread. This restriction is essential for maintaining the integrity and stability of the application. The primary reason behind this is that Qt's GUI classes are not thread-safe. Accessing or modifying them from multiple threads simultaneously can lead to race conditions, crashes, or undefined behavior.
To safely communicate between threads and the main GUI thread, Qt provides a powerful mechanism called signals and slots. This mechanism allows you to send notifications from one thread to another in a thread-safe manner. You can connect the setter function, for example setEnabled of BtnOpen to a custom signalSetEnabled(bool) that you emit from the thread.
//Worker Thread Class
#include <QObject> #include <QThread> class Worker : public QObject { Q_OBJECT public slots: void doWork() { // Simulate a time-consuming task QThread::sleep(2); // Emit a signal to update the GUI (disable the button) emit workDone(); } signals: void workDone(); };
//Main Window Class
#include <QMainWindow> #include <QPushButton> #include <QVBoxLayout> #include <QThread> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { button = new QPushButton("Start Work", this); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(button); QWidget *widget = new QWidget(this); widget->setLayout(layout); setCentralWidget(widget); // Create worker and thread Worker *worker = new Worker(); QThread *workerThread = new QThread(); // Move worker to the new thread worker->moveToThread(workerThread); // Connect signals and slots connect(button, &QPushButton::clicked, this, &MainWindow::onButtonClicked); connect(this, &MainWindow::startWork, worker, &Worker::doWork); connect(worker, &Worker::workDone, this, &MainWindow::onWorkDone); connect(workerThread, &QThread::finished, worker, &QObject::deleteLater); // Start the worker thread workerThread->start(); } signals: void startWork(); public slots: void onButtonClicked() { button->setEnabled(false); emit startWork(); } void onWorkDone() { button->setEnabled(true); } private: QPushButton *button; }; #include "main.moc"
#include <QApplication> #include "MainWindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow mainWindow; mainWindow.show(); return app.exec(); }