【问题标题】:Recreate QMovie upon resizing the widget调整小部件大小时重新创建 QMovie
【发布时间】:2023-02-15 18:00:13
【问题描述】:

调整大小时重新创建 QMovie 小部件的“正确”方法是什么?

class Gif : public QPushButton
{
    Q_OBJECT

public:

    QMovie* movie = nullptr;
    QTimer *timer = new QTimer(this);

    int widget_width = 0;
    int widget_height = 0;

    Gif(QWidget* parent = 0) : QPushButton(parent) { }



    void paintEvent(QPaintEvent* p)
    {
        // Check if the widget has been resized, if so 
        // delete the QLabel/QMovie and recreate them.
        if (widget_width)
        {
            if (widget_width != width())
            {
                QLabel* label = this->findChild<QLabel*>("label");
                label->deleteLater();
                movie->deleteLater();
                movie = nullptr;
            }
        }



        // Load the gif into the QMovie/QLabel.
        if (!movie)
        {
            auto StyleSheet = styleSheet();

            QVector<QString> matches;
            QRegularExpression re(R"(image:\s*url\((.*)\);)");
            QRegularExpressionMatch m = re.match(StyleSheet);

            for (int i = 0; i <= m.lastCapturedIndex(); i++)
                matches.append(m.captured(i));

            movie = new QMovie(matches[1]);
            if (!movie->isValid())
                qDebug() << "failed to create the QMovie.";

            QLabel* label = new QLabel(this);
            label->setObjectName("label");

            widget_width = width();
            widget_height = height();

            label->setGeometry(0, 0, widget_width, widget_height);
            label->setMovie(movie);
            label->show();

            movie->setScaledSize(QSize().scaled(widget_width, widget_height, Qt::IgnoreAspectRatio));
            movie->setSpeed(150);
            movie->start();
        }



        // Pause for 2 seconds after getting into the 
        // last frame.
        if (movie->currentFrameNumber() == (movie->frameCount() -1))
        {
            movie->stop();
            connect(timer, SIGNAL(timeout()), this, SLOT(resume()));
            timer->start(2000);
        }


    }


public slots:

    void resume()
    {
        movie->start();
    }
    
};

调用deleteLater()然后将movie分配给nullptr是否“安全”?不会导致任何内存泄漏/UB?

                if (widget_width != width())
                {
                    QLabel* label = this->findChild<QLabel*>("label");
                    label->deleteLater();
                    movie->deleteLater();
                    movie = nullptr;
                }

另外,除了 QMovie 之外,还有其他方法可以在 gui 中播放 gif 吗?当 gif 为中/大尺寸时,它会占用大量 CPU

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    抱歉,我无法回答您的主要问题。

    关于你的第二个问题,播放 QMovie 时“大量 CPU 使用率”。我找到了一种设置 QMovie 的 CacheMode 的方法。这将有助于减少 QMovie 播放 gif 的 CPU 使用率。

    movie.setCacheMode(QMovie.CacheMode.CacheAll)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 2011-05-18
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      相关资源
      最近更新 更多