Qml 计算实际帧率(FPS)的方法

【写在前面】

        在 Qml 中,任何可视化的项的显示 ( 渲染 ) 都依赖一个根 QQuickWindow,它包含了底层的场景图渲染器。

        因此,如果我们想要在 Qml 中获取 FPS,则只需要在窗口渲染场景图时记录帧数并计算帧率。

        不过,需要注意的是:GUI 程序一般不会频繁刷新,并不建议使用循环 update() 来计算 ( 可行但并非最佳 )。


【正文开始】

       先来看看效果图 ( 屏幕刷新率 165Hz,截屏时无法达到 ):

        实际上,QQuickWindow 提供了 afterRendering():它是渲染完成时发出的信号。

        所以我们只需简单连接即可轻松计算帧率。

        首先,我们简单继承 QQuickItem

#ifndef FPSITEM_H
#define FPSITEM_H

#include <QQuickItem>

class FpsItem : public QQuickItem
{
    Q_OBJECT

    Q_PROPERTY(int fps READ fps NOTIFY fpsChanged)

public:
    FpsItem(QQuickItem *parent = nullptr);

    int fps() const;

signals:
    void fpsChanged();

private:
    int m_fps = 0;
    int m_frameCount = 0;
};

#endif // FPSITEM_H

        然后,连接到 QQuickWindow::afterRendering 累加帧数,定时器来定时更新帧率即可:

#include "fpsitem.h"

#include <QQuickWindow>
#include <QTimer>

FpsItem::FpsItem(QQuickItem *parent)
    : QQuickItem(parent)
{
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [this]{ m_fps = m_frameCount; m_frameCount = 0; emit fpsChanged(); });
    connect(this, &QQuickItem::windowChanged, this, [this]{
        if (window())
            connect(window(), &QQuickWindow::afterRendering, this
                    , [this]{ m_frameCount++; }, Qt::DirectConnection);
    });
    timer->start(1000);
}

int FpsItem::fps() const
{
    return m_fps;
}

        最后,导入到 Qml 中使用就相当简单了 ( 删除了部分不重要的,完整的直接看源码 ):

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Shapes 1.15

import an.item 1.0

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("FpsItem Test")

    FpsItem {
        id: fpsItem
    }

    Item {
        id: back
        anchors.fill: parent

        Text {
            anchors.left: parent.left
            anchors.top: parent.top
            anchors.margins: 10
            font.pointSize: 12
            text: "FPS: " + fpsItem.fps
            color: "red"
        }
    }
}

【结语】

        也许你想计算的是 Item 的单独帧率,然而大部分时候这是没有意义的,所有的 QQuickItem 的渲染皆是由其所在的 QQuickWindow 调用引起的,此时计算的帧率即是其窗口的帧率。

        当然,在于自定义场景图渲染时是有意义的,方法同样简单:

        在 QQuickItem::setFlag(ItemHasContents) 后,所有的 QQuickItem::update() 都会相应的调用 QQuickItem::updatePaintNode(),此时即为该项的帧率。

        最后,附上项目链接(多多star呀..⭐_⭐):

        CSDN的:Qml计算实际帧率(FPS)的方法-C++文档类资源-CSDN下载        在Qml中,任何可视化的项的显示( 渲染)都依赖一个根QQuickWin更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/u011283226/85902072        Github的:GitHub - mengps/QmlControls: Qt / Qml 控件Qt / Qml 控件. Contribute to mengps/QmlControls development by creating an account on GitHub.https://github.com/mengps/QmlControls

猜你喜欢

转载自blog.csdn.net/u011283226/article/details/125591779
QML