Show FPS in QML

后端 未结 2 1454
予麋鹿
予麋鹿 2021-02-04 14:42

Is there a \"simple\" way to show the FPS (frame rate) in a QML/c++ application. All animations and views are done in QML and the application logic is in c++.

I already

相关标签:
2条回答
  • 2021-02-04 15:07

    QML FPS Counter, without affecting performance.

    Project of QNanoPainter and others in qt-labs are using the refresh of an animation of a QML Item to create an FPS counter. It's so easy to being done, attached a project that uses this technique ( modified from QNanoPainter FPS counter ).

    FpsItem code:

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

    Using it as:

    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
        }
    
    }
    
    0 讨论(0)
  • 2021-02-04 15:20

    You have to create your own FPS QQuickItem (or QQuickPaintedItem) and register in your main.cpp to be available in your QML code.

    Here an example.

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

    You can get any other implementation in Internet with a quick search.

    0 讨论(0)
提交回复
热议问题