c++ 调整小工具大小时重新创建QMovie

eqoofvh9  于 2023-02-17  发布在  其他
关注(0)|答案(1)|浏览(168)

调整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;
                }

另外,在GUI中播放gif时,有没有QMovie的替代品?当gif为中等/高大小时,它会占用大量CPU

lmyy7pcs

lmyy7pcs1#

对不起,我不能回答你的主要问题。
关于你的第二个问题,“播放QMovie时CPU使用量很大”,我发现了一个设置QMovie的CacheMode的方法,它将有助于降低QMovie播放gif时的CPU使用量。

movie.setCacheMode(QMovie.CacheMode.CacheAll)

相关问题