How to know thread is running from different button ?
-
Dear All,
I create a button and make it run a infinity loop thread:
void MainWindow::on_pushButton_2_clicked() { MyThread *T3Thread = new MyThread; T3Thread->start(); // <-- in run is a infinity loop with delay(20) }
Now I want to check if T3 thread is running by
void MainWindow::on_pushButton_3_clicked() { MyThread *T3Thread = new MyThread; if(T3Thread->isRunning()) qDebug()<<"T3 thread is running"; }
I believe everyone can see the mistake, T3Thread in button_2 is different from button_3 so T3Thread->isRunning() will never return true.
What should I do ?
Thanks for any suggestions.
-
t3 just a local variable?Why not use member variables
-
@a-normal-worker said in How to know thread is running from different button ?:
t3 just a local variable?Why not use member variables
Do you mean a global variable ?
-
@a-normal-worker said in How to know thread is running from different button ?:
t3 just a local variable?Why not use member variables
If I change T3Thread to global variable, then I met a different situation:
I wrote a myThread.h, inside this header file, I create a "my thread class":class MyThread : public QThread { Q_OBJECT signals: private: void run() { while(1) { for (int i = 0; i <= 100; i++) delay(20); } } };
In order to declare a global variable, I add this line to mainwindow.h :
private: MyThread *T3Thread;
However, because mainwindow.h do not know "MyThread", so I include "myThread.h" to mainwindow.h.
Then compiler said "redefine of class xxxxx"So....I cannot include another header file ? How to declare a variable like "MyThread *T3Thread" correctly.
Thanks everyone.
-
@Hiloshi Does your myThread.h header file has an "include guard"? See https://en.wikipedia.org/wiki/Include_guard
They usually look like:#ifndef MYTHREAD_H #define MYTHREAD_H class MyThread... #endif
Another note: since T3Thread is a pointer you do not need to include myThread.h in mainwindow.h. Instead use forward declaration:
// In mainwindow.h before MainWindow class class MyThread;
and include myThread.h in mainwindow.cpp.
One more note: T3Thread is NOT a global variable (and this is good), it is an class member variable.
-
@a-normal-worker "You should make sure that you use a class member variable or they point to the same object" - he already does in his last post.
-
Dear @jsulm , @a-normal-worker ,
Thank you all. First, the "redefine of class xxxxx" issue may cause by a silly mistake:
#ifndef MYTHREAD_H #define MYTHREAD_H #endif class MyThread // <--I put my code here.
After fix above mistake and declare T3Thread pointer correctly then can compiler successfully.
But running the program show a strange message: "Process killed by signal"
In MyThread.h:
class MyThread : public QThread { Q_OBJECT private: void run() { for (int i = 0; i <= 100; i++) { delay(20); } } };
In mainwindow.h:
class MyThread; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_pressed(); void on_pushButton_2_clicked(); private: Ui::MainWindow *ui; MyThread *T3Thread; };
In mainwindow.cpp:
#include "mythread.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); MyThread *T3Thread = new MyThread; T3Thread->start(); } void MainWindow::on_pushButton_12_clicked() { T3Thread->start(); }
When I run the program, the screen show as normal, but when I press button_2, the screen close suddently, and show "Process killed by signal" on QT terminal.
I suspect that problem is cause by T3Thread->start(), however, if I didn't press button_2, nothing happened.
T3Thread should also executed while creating main window?Do I lack some declaration ?
-
Your constructor is wrong. You are shadowing your T3Thread member variable. Thus when you call
on_pushButton_12_clicked
you are trying to access an uninitialised pointer hence the crash. -
Sorry to confuse you, I didn't explain clearly.
If I use "new" and "T3Thread->start" in the same area, then it will no error(process killed by signal),
as below:
https://www.dropbox.com/s/0488sqlhgn9u4wf/Screenshot from 2017-04-06 09-28-32.png?dl=0
However, if I put them in different place, application will crash and return "process killed by signal",
as below:
https://www.dropbox.com/s/3dfists06z3c5q9/Screenshot from 2017-04-06 09-33-10.png?dl=0
Moreover, if I put "new" just after the "ui->setupUi(this)" and "T3Thread in the on_pushButton_clicked,
it will show a warning message "unused variable ‘T3Thread’ [-Wunused-variable]".@SGaist , I think maybe this is what you said : "uninitialised pointer " .
But, I am sorry, I don't know how to correct it.
-
Remove
MyThread *
from your constructor. -
@Hiloshi You should really read more carefully what others are writing. What @SGaist said is:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); T3Thread = new MyThread; // Remove MyThread* - else you are declaring a local variable which is completely unrelated to the one in your header! T3Thread->start(); }
And after this change think about where to start the thread: in the code you posted you're doing it twice.
-
I want to study in depth in this question. In the original question, I have a running T3Thread, mainwindow cannot reach T3Thread, thanks for @a-normal-worker 's suggestion, we can make T3Thread as a class member of mainwindow then mainwindow have ability to access T3Thread.
Can we use signal/slot instead of using class member ?
-
What exactly do you want to do with your thread ?
-
Dear @SGaist ,
I am thinking to create a breathing LED in my thread, "run" function is keep turn on/off LED.
I want to put one button on mainwindow to start the thread.I do not want this button to be pressed twice ( or thread will create twice), so in the button I put:
void MainWindow::on_pushButton_3_clicked() { if(T3Thread->isRunning()==false) { MyThread *T3Thread = new MyThread; // local variable T3Thread->start; } else qDebug()<<"T3 thread is running"; }
If I do not want to use class member, can I use signal/slot to know T3Thread is running or not ?
Thanks.
-
@Hiloshi
ok, I think we talk at cross here.Here's a basic setup to check if your thread is running when you press a Button, if its not running the button will start the thread:
//in your header: example.h #include <QThread> #include <qDebug> private: QThread *thread;
//in your source file //Constructor { ui->setupUi(this); thread = new QThread; .... } void on_pushButton_clicked(){ if(thread->isRunning()) qDebug() << "Thread is running"; else{ qDebug() << "Thread started"; thread->start(); } } //Destructor { if(thread->isRunning()){ thread->quit(); thread-> wait(); } ... delete ui; }
-
What is the problem with using a member variable to handle that thread object properly ?