How to get a direct jump in QSlider without damaging performance

1.5k views Asked by At

I am now creating a simple video player in QT.

I created a slider that is connected with Connect to a multimedia player (he is responsible for running the movie back and forth) and I want it to be moved by a mouse click anywhere on the slide and not just by dragging the cursor.

I tried to do this by adding my own method as follows:

class MySlider : public QSlider
{

protected:
  void mousePressEvent(QMouseEvent *event)
  {
      if (event->button() == Qt::LeftButton)
      {
          if (orientation() == Qt::Horizontal)
          {
              setValue(minimum() + (maximum() - minimum()) * (static_cast<float>(event->x()) / static_cast<float>(width())));
          }
          event->accept();
      }
      QSlider::mousePressEvent(event);
  }

};

This is the way I connected the slide to the player:

connect(player, &QMediaPlayer::durationChanged,pos_slider, &MySlider::setMaximum );
connect(player, &QMediaPlayer::positionChanged,pos_slider, &MySlider::setValue );

connect(pos_slider, &MySlider::sliderMoved, player, &QMediaPlayer::setPosition);
connect(pos_slider, &MySlider::valueChanged ,player, &QMediaPlayer::setPosition );

My problem is that now when the movie is playing, there is lag (the movie hangs for a few seconds every few seconds). In my opinion, because of this addition, I am actually putting a lot more pressure on the player because he has now added events to listen and send.

How can I get the slider moving in a way that will not damage the performance of the player? (Or reduce the performance degradation to a minimum)

thank you yoko

p.s.

The center of the problem is that I use connect(player, &QMediaPlayer::positionChanged,pos_slider, &MySlider::setValue ); in the media player and also connect(pos_slider, &MySlider::valueChanged ,player, &QMediaPlayer::setPosition ); , this duplication is causing performance problems, but I have no idea how I can get rid of this duplication

1

There are 1 answers

1
m7913d On BEST ANSWER

As you pointed out yourself, the problem is (probably) due to resonance between QMediaPlayer::position and MySlider::value.

Solution 1:

So, you should avoid changing the QMediaPlayer::position when MySlider::value is updated programmatically, i.e. do not use the following connection:

connect(pos_slider, &MySlider::valueChanged ,player, &QMediaPlayer::setPosition );

Instead, you should use the sliderReleased and sliderMoved signals to update QMediaPlayer::position and call QMediaPlayer::setPosition manually inside mousePressEvent (when appropriate).

Solution 2: (thanks too Karsten Koop)

Create your own slot to update the slider value when QMediaPlayer::position changed to block emitting signals.

connect(player, &QMediaPlayer::positionChanged,pos_slider, &MySlider::updateValueFromMediaPlayer );

void MySlider::updateValueFromMediaPlayer(int pos)
{
    blockSignals(true); 
    setValue(pos); 
    blockSignals(false);
}

Note that you do not need the following connection in this case:

connect(pos_slider, &MySlider::sliderMoved, player, &QMediaPlayer::setPosition);