【问题标题】:How to get a direct jump in QSlider without damaging performance如何在不损害性能的情况下直接跳转 QSlider
【发布时间】:2018-02-28 16:33:56
【问题描述】:

我现在正在 QT 中创建一个简单的视频播放器。

我创建了一个与连接到多媒体播放器(他负责来回播放电影)连接的滑块,我希望通过鼠标单击幻灯片上的任意位置来移动它,而不仅仅是拖动光标.

我尝试通过添加自己的方法来做到这一点,如下所示:

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

};

这是我将幻灯片连接到播放器的方式:

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

我的问题是现在播放电影时会有延迟(电影每隔几秒钟就会挂起几秒钟)。在我看来,由于这个添加,我实际上给玩家施加了更大的压力,因为他现在添加了要监听和发送的事件。

如何让滑块以不会损害播放器性能的方式移动? (或者将性能下降降到最低)

谢谢 洋子

附言

问题的中心是我在媒体播放器中使用 connect(player, &amp;QMediaPlayer::positionChanged,pos_slider, &amp;MySlider::setValue );connect(pos_slider, &amp;MySlider::valueChanged ,player, &amp;QMediaPlayer::setPosition ); ,这种重复导致性能问题,但我不知道如何摆脱这种重复

【问题讨论】:

  • 鼠标点击事件可能与它无关,但positionChanged 事件可能会经常发出,因为参数是以毫秒为单位的位置。我仍然不希望仅从处理程序中挂起几秒钟。你能试着找出处理程序被调用的频率吗?另外,添加此处理程序时 CPU 使用率是否增加?
  • 你的两个处理程序也可能在一个循环中互相调用,但收敛速度很慢;您可以使用blockSignals 暂时阻止事件的发射
  • @KarstenKoop 我知道这个循环是问题,但我能做什么?我需要它根据视频位置更新它的位置,还需要视频根据滚动条位置更新他的位置,我没有找到这样做的选项接受使用这个循环...
  • 您可以使用blockSignals 暂时禁用事件。不要将positionChanged 连接到滑块的setValue,而是将其连接到您自己的插槽,您可以在其中放置pos_slider-&gt;blockSignals(true); pos_slider-&gt;setValue(); pos_slider-&gt;blockSignals(false); 之类的东西
  • 听起来还是很没效率

标签: qt qtmultimedia qt-events


【解决方案1】:

正如您自己指出的那样,问题(可能)是由于QMediaPlayer::positionMySlider::value 之间的共振。

解决方案 1:

因此,当MySlider::value 以编程方式更新时,您应该避免更改QMediaPlayer::position,即不要使用以下连接:

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

相反,您应该使用sliderReleasedsliderMoved 信号来更新QMediaPlayer::position 并在mousePressEvent 内手动调用QMediaPlayer::setPosition(在适当的时候)。

解决方案 2:(也感谢 Karsten Koop)

QMediaPlayer::position 更改为阻止发射信号时,创建您自己的插槽以更新滑块值。

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

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

请注意,在这种情况下您不需要以下连接:

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

【讨论】:

  • setValue();改成setValue(pos);:P
猜你喜欢
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多