【问题标题】:Show FPS in QML在 QML 中显示 FPS
【发布时间】:2016-06-03 21:19:07
【问题描述】:

是否有一种“简单”的方式可以在 QML/c++ 应用程序中显示 FPS(帧速率)。 所有动画和视图都在 QML 中完成,应用程序逻辑在 c++ 中。

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

export QML_SHOW_FRAMERATE=1

【问题讨论】:

    标签: c++ linux qt qml frame-rate


    【解决方案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)
                }
        }
    

    您可以通过快速搜索获得 Internet 中的任何其他实现。

    【讨论】:

    【解决方案2】:

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

    QNanoPainter 和 qt-labs 中的其他项目正在使用刷新 QML 项目的动画来创建 FPS 计数器。做起来很容易,附上一个使用这种技术的项目(修改自QNanoPainter FPS counter)。

    FpsItem 代码:​​

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

    【讨论】:

      【解决方案3】:

      我研究了一下主题。我通常使用@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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多