PDA

View Full Version : Update widgets independently and simultaneously



JasonKretzer
12th July 2013, 13:32
Using 5.0.2 on Win 7

I have 2 "ImageLoop" classes [which extend QWidget] where each take up half the screen, split vertically. Each contains a QLabel for displaying a list of jpg files. So, inside a for loop, I give each widget their list of images, and emit a "listfull" signal which I have connected to a slot - "playList" - in each of the two widgets. Unfortunately, it appears that only the first widget's signal ever gets emitted as only the first widget is ever updated.

I am new to Qt programming and maybe I am misunderstanding the slot/signal system. I thought the pseudocode below would, for each instance, fill the list, emit the signal, and each instance would go off on their merry way -- basically each widget simultaneously and independently showing images. So, question is what am I missing? Or am I going to have to spawn each of these in their own thread?

Thanks!

Pseudocode


for(int i=0; i<2; i++){
Create ImageLoop instance
connect(instance, SIGNAL(listfull()), instance, SLOT(playList()));
instance->FillList(arrayOfImageFileNames);
}

//inside of ImageLoop class
void FillList(arrayOfImageFileNames) {
//adds all files to an internal list
//when finished
emit listfull();
}

//inside of ImageLoop class
void playList() {
//code to loop through each image and show it
}

Santosh Reddy
12th July 2013, 13:45
I am new to Qt programming and maybe I am misunderstanding the slot/signal system. I thought the pseudocode below would, for each instance, fill the list, emit the signal, and each instance would go off on their merry way-- basically each widget simultaneously and independently showing images
NO, each widget (QLable in your case) will be painted (upated) one after another.

Your code does not show any problem, it should word as you ecpected but in a a sequence (one after another) not is parallel. Check if there are any messages in Applicatio output, also make user Q_OBJECT macro is defined and signal and slots are declared in proper sections of class definiction.

JasonKretzer
12th July 2013, 13:52
Thank you sir. I receive no errors or other indication in my application output and I have the signals and slots properly set up in my class definition. One big indicator is that it works for the first widget. So, what would I need to get them to run in parallel?

Santosh Reddy
12th July 2013, 13:56
One possible problem could be (as the actual code is not shown) that the your playlist() function has a non returning loop.

JasonKretzer
12th July 2013, 13:58
This is true, it does not. Each widget just needs to sit there and loop over the list of images over and over.

Santosh Reddy
12th July 2013, 14:36
You cannot do so.

If you need to update the both the widgets often then use a timer to trigger the signals to update, and DO NOT use non retunring loops, it will cause the GUI (or parts of GUI) to not respond (freeze/Hang)

JasonKretzer
12th July 2013, 15:06
That is just it, each of those methods use a qtimer to change out the images. The problem is that it is only showing the first imageloop instance. The other half of the screen is black and never shows.

Could I put each instance in its own QThread? Would that make it work? The gui being responsive is not a huge deal as the whole point is to start the program and let the two sections of the screen each run through their list of images until the program is shutdown.

Santosh Reddy
12th July 2013, 15:32
Could I put each instance in its own QThread? Would that make it work?
No, GUI components cannot be directly updaated from QThread.

Only option you have is to use timer (QTimer / QObject::startTimer()), which is lot sipler than QThread

JasonKretzer
12th July 2013, 15:43
So, would change code like this?



for(int i=0; i<2; i++){
Create ImageLoop instance
instance->FillList(arrayOfImageFileNames);
}

//inside of ImageLoop class
void FillList(arrayOfImageFileNames) {
//adds all files to an internal list
//when finished
QTimer::singleShot(0, this, SLOT(playList()));
}

//inside of ImageLoop class
void playList() {
//code to loop through each image and show it
}

Santosh Reddy
12th July 2013, 21:39
1. You have to use multi-shot timer
2. In playList() slot update each image and return, so that on next timeout the slot is called again

JasonKretzer
12th July 2013, 21:41
Gotcha! thanks. I have it now. I appreciate the help.