在 QML/C++ 应用程序中是否有一种“简单”的方法来显示 FPS(frame rate 帧率) ?
为了达到这个目的,我们必须创建自己的获取 FPS 的 QQuickItem(或 QQuickPaintedItem) 类,并在 main.cpp
中完成注册,以便在 QML 代码中使用它。
头文件 FPSText.h
的代码如下:
#ifndef FPSTEXT_H_7FE54CFA_E610_4C32_A4D7_A7AF0E56FF04
#define FPSTEXT_H_7FE54CFA_E610_4C32_A4D7_A7AF0E56FF04
#include <QQuickPaintedItem>
class FPSText : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(int fps READ fps NOTIFY fpsChanged)
public:
FPSText(QQuickItem *parent = nullptr);
~FPSText();
void paint(QPainter *painter);
int fps() const {
return _currentFPS;
}
signals:
void fpsChanged(int);
private:
void recalculateFPS();
int _currentFPS;
int _cacheCount;
QVector<qint64> _times;
};
#endif // FPSTEXT_H_7FE54CFA_E610_4C32_A4D7_A7AF0E56FF04
实现文件 FPSText.cpp
的代码如下:
#include "FPSText.h"
#include <QDateTime>
#include <QPainter>
FPSText::FPSText(QQuickItem *parent)
: QQuickPaintedItem(parent)
, _currentFPS(0)
, _cacheCount(0)
{
_times.clear();
setFlag(QQuickItem::ItemHasContents);
}
FPSText::~FPSText()
{
}
void FPSText::paint(QPainter *painter)
{
recalculateFPS();
painter->save();
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);
painter->restore();
update();
}
void FPSText::recalculateFPS()
{
qint64 currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
_times.push_back(currentTime);
while (currentTime - _times.at(0) > 1000) {
_times.pop_front();
}
int currentCount = _times.length();
_currentFPS = (currentCount + _cacheCount) / 2;
if (currentCount != _cacheCount) {
emit fpsChanged(_currentFPS);
}
_cacheCount = currentCount;
}
在 main.cpp
中进行注册的代码如下:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QQmlComponent>
#include "FPSText.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<FPSText>("FPSText", 1, 0, "FPSText"); // 注册
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
测试使用的 QML 的代码如下:
import QtQuick 2.12
import QtQuick.Window 2.12
import FPSText 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello FPSText")
FPSText {
width: 200
height: 200
anchors.centerIn: parent
Text {
anchors.centerIn: parent
text: parent.fps.toFixed(2)
}
}
}
参考链接: Show FPS in QML