QPushButton only responds with QApplication::processEvents
-
Hi,
I have an odd problem. I'm working on building a Qt application within a larger one which I don't have the code. This application allows you to build plugin dlls to work in conjunction with the larger application. It mostly works but the issue I'm having is I created a progress bar form that has a progress bar and a button. When I click the button there is no response when I do a lot of work in the main GUI thread. The progressBar does update appropriately. So, I then added a thread to off load the work to that thread hoping that when I click the button it would respond, but that too does not work. It appears that the only way to get a button response after clicking it is if the class that does all the work issues processEvents every so often. Problem is when that happens the main application I'm working under flashes because that too is a Qt application.
My question is there a way I can force my application to go to the main GUI thread without using processEvents? It's weird that the progress bar is updating but the button does not respond.
Thanks!
-
Hi,
I have an odd problem. I'm working on building a Qt application within a larger one which I don't have the code. This application allows you to build plugin dlls to work in conjunction with the larger application. It mostly works but the issue I'm having is I created a progress bar form that has a progress bar and a button. When I click the button there is no response when I do a lot of work in the main GUI thread. The progressBar does update appropriately. So, I then added a thread to off load the work to that thread hoping that when I click the button it would respond, but that too does not work. It appears that the only way to get a button response after clicking it is if the class that does all the work issues processEvents every so often. Problem is when that happens the main application I'm working under flashes because that too is a Qt application.
My question is there a way I can force my application to go to the main GUI thread without using processEvents? It's weird that the progress bar is updating but the button does not respond.
Thanks!
You somewhere block the Qt event loop. Looks like your attempt to move the stuff into a separate thread was not successful. Use a debugger to see whats going on in the main thread.
-
You somewhere block the Qt event loop. Looks like your attempt to move the stuff into a separate thread was not successful. Use a debugger to see whats going on in the main thread.
@Christian-Ehrlicher I wish I could. The result is a dll that is copied into the plugin folder of the main system. It loads my dll and runs it. I can only place print statements to debug.
-
@Christian-Ehrlicher I wish I could. The result is a dll that is copied into the plugin folder of the main system. It loads my dll and runs it. I can only place print statements to debug.
Then write test cases so you can test it without the other application. How do you test your code??
-
Then write test cases so you can test it without the other application. How do you test your code??
@Christian-Ehrlicher I put print statements everywhere. I always used a debugger in the past for this project I can't.
-
@Christian-Ehrlicher I put print statements everywhere. I always used a debugger in the past for this project I can't.
-
@leinad If I use threads which happen to have a heavy workload, shouldn't the system relinquish time to the main GUI thread? It seems I can never get a button click response. What other method other than processEvents can I use to do this?
Hi,
How are you using that thread ?
Did you implement the worker object approach ?
Reimplement the run method ?
Are you using signals and slots ? -
Hi,
How are you using that thread ?
Did you implement the worker object approach ?
Reimplement the run method ?
Are you using signals and slots ?@SGaist Here is an example:
Worker *worker = new Worker; QThread* Thread = new QThread; Thread->setObjectName("Thread"); worker->moveToThread(Thread); connect(worker, SIGNAL(finished()), Thread, SLOT(quit())); connect(worker, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(Thread, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(this, SIGNAL(sendExit()), worker, SLOT(exit()), Qt::DirectConnection); Thread->start();I run a few threads and use signal slots for communication like sending data.
-
@SGaist Here is an example:
Worker *worker = new Worker; QThread* Thread = new QThread; Thread->setObjectName("Thread"); worker->moveToThread(Thread); connect(worker, SIGNAL(finished()), Thread, SLOT(quit())); connect(worker, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(Thread, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(this, SIGNAL(sendExit()), worker, SLOT(exit()), Qt::DirectConnection); Thread->start();I run a few threads and use signal slots for communication like sending data.
This is not a minimal, compilable example. It does not even start anything in the worker object.
-
@SGaist Here is an example:
Worker *worker = new Worker; QThread* Thread = new QThread; Thread->setObjectName("Thread"); worker->moveToThread(Thread); connect(worker, SIGNAL(finished()), Thread, SLOT(quit())); connect(worker, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(Thread, SIGNAL(finished()), Thread, SLOT(deleteLater())); connect(this, SIGNAL(sendExit()), worker, SLOT(exit()), Qt::DirectConnection); Thread->start();I run a few threads and use signal slots for communication like sending data.
@leinad The question I was asked is how do I start a thread with a worker object. This is how I start a thread and attach a worker object to it. I know the thread starts because I am able to send data between them. My code is complicated and integrated with a 3rd party source.
The original question is if I run threads that do a lot of processing, shouldn't at some point the system relinquish to the main GUI thread so it can process pushbuttons, etc? It seems the only way I can do that is to use processEvents every so often to interrupt the current processing so as to check if the button was pressed. I really hate doing that. -
@leinad The question I was asked is how do I start a thread with a worker object. This is how I start a thread and attach a worker object to it. I know the thread starts because I am able to send data between them. My code is complicated and integrated with a 3rd party source.
The original question is if I run threads that do a lot of processing, shouldn't at some point the system relinquish to the main GUI thread so it can process pushbuttons, etc? It seems the only way I can do that is to use processEvents every so often to interrupt the current processing so as to check if the button was pressed. I really hate doing that.@leinad said in QPushButton only responds with QApplication::processEvents:
The original question is if I run threads that do a lot of processing, shouldn't at some point the system relinquish to the main GUI thread so it can process pushbuttons, etc?
Then you dont understand how threads work... unless you are blocking, the system usually keeps hopping between threads. e.g 2s processing Thread A, 5s Thread C, 2s Thread B, 7s Thread C and then 1s Thread A again.
-
@leinad said in QPushButton only responds with QApplication::processEvents:
The original question is if I run threads that do a lot of processing, shouldn't at some point the system relinquish to the main GUI thread so it can process pushbuttons, etc?
Then you dont understand how threads work... unless you are blocking, the system usually keeps hopping between threads. e.g 2s processing Thread A, 5s Thread C, 2s Thread B, 7s Thread C and then 1s Thread A again.
-
@Pl45m4 Right, but eventually it should go back to the main thread correct? I'm not sure what you mean by blocking? None of the threads are stuck on anything, they just run one at a time but they do a lot of processing.
Hard to say what's going on exactly... unless you have an example where you can reproduce this behavior.
The code above doesn't help.Also:
@leinad said in QPushButton only responds with QApplication::processEvents:
connect(this, SIGNAL(sendExit()), worker, SLOT(exit()), Qt::DirectConnection);
Better let Qt decide what type of connection is needed.
Forcing aDirectConnectionwhen dealing with threads is in most of the cases a bad idea... -
Hard to say what's going on exactly... unless you have an example where you can reproduce this behavior.
The code above doesn't help.Also:
@leinad said in QPushButton only responds with QApplication::processEvents:
connect(this, SIGNAL(sendExit()), worker, SLOT(exit()), Qt::DirectConnection);
Better let Qt decide what type of connection is needed.
Forcing aDirectConnectionwhen dealing with threads is in most of the cases a bad idea... -
L leinad has marked this topic as solved on