PDA

View Full Version : QMainWindow - QThread - QGraphicsView, what to do with them?



m41n1
12th August 2008, 01:45
Hello everyone.

Well, I am going to start explaining what i wanted to get and then what I tried. This is basically because I don't know if i am doing the right thing. I have an agent-based software for finding solution to a given problem. A solution is given by a vector of id's and its graphical representation is a graph. All these agents have a pointer to the best solution so when one of them finds a better solution, updates the current "best solution". This is done by simulating parallelism, I mean, agent#1 executes its code, and when it finishes agent#2 proceeds. This way there's no problem updating the best solution found.
This software is text-based (a console app) so its really hard to 'understand' the solution. What i was intending to do is just to display this solution on a QMainWindows using QGraphicsView. So I thought I could create a class with a pointer to the best solution that could paint this solution every 2 secs (for example).

I developed a class 'paintable' that inherits from QMainWindow that contains methods to paint the solution. Then I tried creating another class 'SolDisplayer' that inherited from QThread and 'paintable'. The idea was to create a thread to paint this solution every x given seconds. But it seems it's not possible to have two classes inheriting from QObject. This way I thought I could avoid the use of QThread by using QTimer, but it doesn't work either. I don't know what else to try, maybe it's just this should not be done like this. ¿Could you gimme some ideas on how to do this?:(

In this example, I have two main classes, one for changing the vector and the other one for displaing it. This is the code of the classes, maybe it's something wrong. Anyway, both classes work separetedly. If i don't run the class that changes the vector, the display class works smoothy, but if i run that class that suffles the vector, no window is launched.:confused:

http://rafb.net/p/OsNbeN52.html

jacek
12th August 2008, 17:37
First of all remember that you shouldn't touch the GUI from a non-GUI thread.

There are two ways of doing this in Qt. First one is to use one thread. In such case your agents your invoke QApplication::processEvents() from time to time to keep the GUI responsive. The other way is to create a separate thread for the agents. In such case you can use signals and slots mechanism. If an agent finds a solution it can emit a signal with the solution. Then the GUI would receive it, paint it and wait for another signal --- you don't need any timers or polling loops.

You could even make agents completely independent (of course if your algorithm permits that), by eliminating the single best solution. If the solution isn't too big (in terms of memory usage), each agent could have its own copy and you could connect all agents together, so that when one finds a better solution all of them (and the GUI) get a signal. With such approach you can easily decide how many worker threads and agents you want to use.

When it comes to your mod class: to start a thread you have to invoke QThread::start() method. Also don't wait for the thread, because you will block the event loop.

m41n1
12th August 2008, 18:57
Thanks a lot for your explanation :). Just one more question. If an agent finds a solution and then emits a signal, then the viewer recives this signal and start painting the solution, will the agents keep looking for new solutions while the best one is being painted or they will stop until the painting process is finished? I am asking this because it may occur that an agent could try to change the current best solution for a better one while the painter is reading the solution. May this happen? If affirmative, should i use mutex for avoid this situation?

Thanks :)

jacek
12th August 2008, 19:14
If an agent finds a solution and then emits a signal, then the viewer recives this signal and start painting the solution, will the agents keep looking for new solutions while the best one is being painted or they will stop until the painting process is finished?
If agents will run in a separate thread(s), they won't stop.


May this happen? If affirmative, should i use mutex for avoid this situation?
If you will have a single global variable with best solution, then you need a mutex, but you can pass a copy of the solution in the signal --- you won't have to care about synchronization then. It just depends on the size of that "solution", if that's a vector of 100 integers it's not a problem, but if it has few megabytes it might not be a good approach.

You can also consider having two copies of the best solution. One that is used by agents and a copy that is being currently painted.