2016-02-22 18 views
7

Esiste un modo "semplice" per mostrare l'FPS (frame rate) in un'applicazione QML/C++. Tutte le animazioni e le viste vengono eseguite in QML e la logica dell'applicazione è in C++.Mostra FPS in QML

ho già provato a installare QML_SHOW_FRAMERATE in Linux prima di avviare l'applicazione, ma non ha aiutato:

export QML_SHOW_FRAMERATE=1 

risposta

5

È necessario creare il proprio FPS QQuickItem (o QQuickPaintedItem) e registrare nel main.cpp per essere disponibile nel tuo codice QML.

Ecco un esempio.

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

è possibile ottenere qualsiasi altra applicazione in Internet con una rapida ricerca.

+1

vi ringrazio molto! Questo sembra funzionare. Il numero visualizzato rappresenta il valore fps dell'intera vista/applicazione o solo del rettangolo dipinto? Potresti fornire una rapida spiegazione di come funziona? – luffy

+1

@luffy FPSText è gestito da QML Scene Graph: http://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html, e il punto sopra il codice per scdule un ridisegno di ogni frame è FPSText :: update() http://doc.qt.io/qt-5/qquickpainteditem.html#update –

+0

Risolvimi se ho torto ma ... Questo potrebbe potenzialmente creare un ciclo infinito con la consacrazione del drenaggio delle risorse. –

0

Contatore FPS QML, senza influire sulle prestazioni.

Il progetto di QNanoPainter e altri in qt-labs utilizzano l'aggiornamento di un'animazione di un oggetto QML per creare un contatore FPS. È così facile da fare, allegato un progetto che utilizza questa tecnica (modificato da QNanoPainter FPS counter). Codice

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

Usandolo come:

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 
    } 

}