Signals/Slots how to update grahpicsView (May be a macOS X only problem / bug)
-
Hi to all,
I have created a minimal example for my problem. I draw colors to a graphics view scene in between I launch a subprocess. I use signals and slots for all this.
a) The scene does not get updated - except I use QApplication::processEvents.
As far a I have learned this is not recommended.
What command I should use to update?b) Should I update the scene, the element or the graphics view?
c) How can I get all statusbar messages be displayed?
I don't know why I can't paste it here. Maybe it is to much.
A minimal example here: http://files.lacunasolutions.com/various/QtMinimalLoops.zipthx for help and hints
Alexander -
Here is the main part of my example code.
void MainWindow::slotDoSomething(int i) { ui->statusbar->showMessage("Pause at: " + QString::number(i), 0); //QApplication::processEvents(); QThread::sleep(1); } void MainWindow::slotPaintColor( int i){ QPixmap pix(ui->graphicsView->size()); pix.fill(QColor(colors[i].R, colors[i].G, colors[i].B)); pixmap.setPixmap(pix); pixmap.update(); } void MainWindow::on_startButton_released() { ui->statusbar->showMessage("Start loop ...", 0); for( int i = 0; i < 5; i++ ) { ui->statusbar->showMessage("Paint color: " + QString::number(i), 0); emit slotPaintColor(i); ui->statusbar->showMessage("Start subprocess now: " + QString::number(i), 0); emit slotDoSomething(i); } }
-
@ademmler said in Signals/Slots how to update grahpicsView:
The scene does not get updated - except I use QApplication::processEvents.
Your sample uses
QThread::sleep(1);
. This is problematic. Simply do not use anything likesleep()
.So long as you implement the running of your subprocess via the asynchronous signals & slots methods of
QProcess
--- and notQProcess::execute()
orQProcess::waitForFinished()
--- there will be no blocking/freezing. Basically, do everything with signals & slots, not blocking calls like these orQThread::sleep()
. -
thx for your comment - I need to explain more about my example.
-
The sleep replaces my original subroutine.
In this one I do some measurements using a color measurement device.
But this takes also some time to measure ... hence I added sleep for simulation this. -
The two processes of painting and measurement need to be in synchronization.
If I use the suggested method does not work at all. -
My question was not about QThread or QProcess.
My questions are still open and about using graphicsview properly:
- What signal can I get, after an element has been repainted?
- How can I force a repaint?
- On which of the three elements (grahicsView, scene, pixmap) I should do this repaint/update call?
Regards Alexander
-
-
@ademmler
Not really, because as I said I don't see any need to try to do all this forced repainting etc.I know what you are trying to simulate with your use of
QThread::sleep(1);
, but it is the cause of the problem.What you should do, for your calculations or whatever it is that you will really do there, is one of:
-
If that code can do its work in the main thread via using signals use that. Just as an e.g.,
QProcess
works that way. -
Otherwise, put it in its own thread and simply have that raise signals when it wants to tell the UI thread something to act on.
Now you have no blocking, and the UI thread remains "responsive" while the other thread is running. The other thread is not responsible for "forcing" updates in the UI, those happen when the UI thread gets its timeslice to run.
That's how I would approach it, at least to see what performance is like.
-
-
If that code can do its work in the main thread via using signals use that. Just as an e.g., QProcess works that way.
The process is not a "system process" - what's going on in the SDK of the measurement device is a "black box" for me.
Otherwise, put it in its own thread and simply have that raise signals when it wants to tell the UI thread something to act on.
For my minimal example this would mean "void MainWindow::slotDoSomething(int i)" will emit a signal to get the main process to "paint" the next color. Which is the invers version of my actual sample. right?
I tried this out - but still - the color does not change without QApplication::processEvents();
Hence again the question: how to get the colored pixmap to be updated ...Here is the actual code for download: http://files.lacunasolutions.com/various/QtMinimalLoopsV2.zip
-
@ademmler
I'm sorry, I don't download code.As I said, the calculation ("measurement device") needs to be its own thread, so that it can block if it wants. That sends signals when it has something to say. The main GUI acts on that and does updates when its thread is running. I would not expect
QApplication::processEvents()
anywhere.I leave it to you/others now, who perhaps can help you more.
-
@JonB
Sorry Jon - I understand that you down download. But without the code you will not understand me.
I am already using signals and slots and the problem still exists. I think this is even a MacOS X related problem/bug, because on windows we do not have this issue.How can I paste all code into this windows here? The amount of text seems to be limited ...