qtqtmultimediaqt-events

How to get a direct jump in QSlider without damaging performance


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


Solution

  • 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);