August 5, 2010

Sohoquetaros Sohoquetaros
Lab Rat
6 posts

Multiple “valueChanged”-events in QSlider

 

Hello,

I noticed some strange behavior with the valueChanged event in QSlider (I’m currently porting from QT3 where I didn’t have those problems).

When I click on an arrow to increment or decrement the slider by one, I receive a valueChanged event. So far so good. But when I do some lengthy computing in a method receiving this event, I will get another valueChanged event – just as If I would have been on the arrow with the mouse for a longer time.

Is there any way to inhibit this behavior? Maybe some property not to react on a mouse held on the arrow?

Any help would be appreciated.

Thanks a lot

7 replies

August 5, 2010

¤ Dii ¤ ¤ Dii ¤
Lab Rat
51 posts

The complicated way is to catch the mouse events, let’s skip this. The not so complicated is to block the signal during your process. Like this:

  1. void yourapp::sliderchanged(int)
  2. {
  3.   ui->yourslider->blocksignals(true);
  4.  
  5.   ... long process ...
  6.  
  7.   ui->yourslider->blocksignals(false); // back to normal
  8. }

Another possibility is to use somewhere (maybe at the start) in your function the

  1. qApp->processEvents();

where your computing will stop for a bit to receive all application events.

Hope this helps.

August 6, 2010

Sohoquetaros Sohoquetaros
Lab Rat
6 posts

Thanks a lot,

“blockSignals” solves the problem.
Thank you for your fast answer !

August 7, 2010

Ivan Čukić Ivan Čukić
Lab Rat
120 posts

The problem with blocking signals is that it blocks the later ones – that is, if you slide from 1 to 10, it will process 1 although (I guess) the more important one would be 10.

If this is undesired, you can use delayed processing of some sorts – add a timer (for eg QBasicTimer) and start it when you get sliderchanged event. Set the delay to be around 100ms.

When you get the last signal, no new ones will appear in the next 100ms and you can freely process the single event. (this is something that is usually done when people implement incremental search)

 Signature 

Ivan Čukić | ivan.cukic(at)kde.org | KDE e.V.
Qt Ambassador

August 7, 2010

Sohoquetaros Sohoquetaros
Lab Rat
6 posts

Mmh, that’s a point.
But I read in the QT-documentation, that QBasicTimer is just for internal use and QTimer should be used instead of.

I try it with QTimer::singleShot with 100ms delay. That should be fine too.

August 8, 2010

Ivan Čukić Ivan Čukić
Lab Rat
120 posts

Since it is public API, it is meant to be used. QTimer is recommended, that is true, but for the basic delay this is (IMO) a better option since it does exactly what is needed with much less overhead.

 Signature 

Ivan Čukić | ivan.cukic(at)kde.org | KDE e.V.
Qt Ambassador

August 9, 2010

Thomas Zander Thomas Zander
Ant Farmer
224 posts

As a general point it is important to avoid doing something in the event handling that takes a lot of time exactly for this kind of problems.

It will block your applications repainting as well because spending time in your calculation at every event will mean you will have less time to repaint.

This is important since the signal you respond to; valueChanged() is emitted before the result of that is painted on screen. So the user will not see the slider move until your calculation is done. If the user moves around the mouse a lot this can cause the repaint to not happen for various seconds. That will look ugly :)

The solution is to make your slot return very quickly; it can be something as simple as
<pre> m_timer.stop(); //stop previous running timer m_timer.start(); // handle the change in 800ms or so
</pre>

Then your timer can read the current value from the slider and do its calculation at most only once per timeout. Making sure that the screen keeps updated in between.

August 11, 2010

Sohoquetaros Sohoquetaros
Lab Rat
6 posts

Well, what shoud I say?

Thanks for so much help!
It really solves the problem.

 
  ‹‹ How To Use VBO in QT with opengl es?      Send special unicode characters via TCP socket? ››

You must log in to post a reply. Not a member yet? Register here!