在 QML 中显示 FPS

Show FPS in QML

本文关键字:FPS 显示 QML      更新时间:2023-10-16

有没有一种"简单"的方法来显示QML/c++应用程序中的FPS(帧速率)。所有动画和视图都在 QML 中完成,应用程序逻辑在 c++ 中完成。

启动应用程序之前,我已经尝试在 Linux 中设置QML_SHOW_FRAMERATE,但它没有帮助:

export QML_SHOW_FRAMERATE=1

您必须创建自己的FPS QQuickItem(或QQuickPaintedItem)并在main中注册.cpp才能在QML代码中使用。

这里有一个例子。

class FPSText: public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(int fps READ fps NOTIFY fpsChanged)
public:
    FPSText(QQuickItem *parent = 0);
    ~FPSText();
    void paint(QPainter *);
    Q_INVOKABLE int fps()const;
signals:
    void fpsChanged(int);
private:
    void recalculateFPS();
    int _currentFPS;
    int _cacheCount;
    QVector<qint64> _times;
};
FPSText::FPSText(QQuickItem *parent): QQuickPaintedItem(parent), _currentFPS(0), _cacheCount(0)
{
    _times.clear();
    setFlag(QQuickItem::ItemHasContents);
}
FPSText::~FPSText()
{
}
void FPSText::recalculateFPS()
{
    qint64 currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
    _times.push_back(currentTime);
    while (_times[0] < currentTime - 1000) {
        _times.pop_front();
    }
    int currentCount = _times.length();
    _currentFPS = (currentCount + _cacheCount) / 2;
    qDebug() << _currentFPS;
    if (currentCount != _cacheCount) fpsChanged(_currentFPS);
    _cacheCount = currentCount;
}
int FPSText::fps()const
{
    return _currentFPS;
}
void FPSText::paint(QPainter *painter)
{
    recalculateFPS();
    //qDebug() << __FUNCTION__;
    QBrush brush(Qt::yellow);
    painter->setBrush(brush);
    painter->setPen(Qt::NoPen);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height(), 0, 0);
    update();
}

QML:

FPSText{
        id: fps_text
        x:0
        y: 0;
        width: 200
        height: 100
        Text {
                anchors.centerIn: parent
                text: fps_text.fps.toFixed(2)
            }
    }

您可以通过快速搜索在互联网上获得任何其他实现。

QML FPS 计数器,而不会影响性能。

QNanoPainter和qt-labs中的其他人的项目正在使用QML项目的动画刷新来创建FPS计数器。它很容易完成,附加一个使用这种技术的项目(从QNanoPainter FPS计数器修改)。

FPS项目代码:

import QtQuick 2.0
import QtQuick.Window 2.2
Rectangle {
    id: root
    property int frameCounter: 0
    property int frameCounterAvg: 0
    property int counter: 0
    property int fps: 0
    property int fpsAvg: 0
    readonly property real dp: Screen.pixelDensity * 25.4/160
    color: "black"
    width:  childrenRect.width + 10*dp;
    height: childrenRect.height + 10*dp;
    Image {
        id: spinnerImage
        anchors.verticalCenter: parent.verticalCenter
        x: 4 * dp
        width: 36 * dp
        height: width
        source: "images/spinner.png"
        NumberAnimation on rotation {
            from:0
            to: 360
            duration: 800
            loops: Animation.Infinite
        }
        onRotationChanged: frameCounter++;
    }
    Text {
        anchors.left: spinnerImage.right
        anchors.leftMargin: 8 * dp
        anchors.verticalCenter: spinnerImage.verticalCenter
        color: "#c0c0c0"
        font.pixelSize: 18 * dp
        text: "Ø " + root.fpsAvg + " | " + root.fps + " fps"
    }
    Timer {
        interval: 2000
        repeat: true
        running: true
        onTriggered: {
            frameCounterAvg += frameCounter;
            root.fps = frameCounter/2;
            counter++;
            frameCounter = 0;
            if (counter >= 3) {
                root.fpsAvg = frameCounterAvg/(2*counter)
                frameCounterAvg = 0;
                counter = 0;
            }
        }
    }
}

将其用作:

import QtQuick 2.9
import QtQuick.Window 2.2
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    FpsItem {
        id: fpsItem
        anchors.centerIn: parent
    }
}

我学习了一下主题。我通常使用@Miguel Angel描述的方法,但我最近使用QQuickWindow::frameSwapped()信号实现了一个更简单的方法。代码和信息可以在这里找到:https://github.com/carlonluca/lqtutils#lqtutils_uih。集成到另一个应用程序中很简单。

我将这两种技术与@forlayo中的一种进行了比较:前两种似乎总是在测量上达成一致,另一种通常不同。

这是比较:https://youtu.be/p_y_kL85R4A。

我还写了一篇博客文章,其中包含更多信息:https://thebugfreeblog.blogspot.com/2021/09/measure-framerate-qt.html