QML 对象不更新显示
Posted
技术标签:
【中文标题】QML 对象不更新显示【英文标题】:QML object does not update on display 【发布时间】:2020-12-22 22:08:44 【问题描述】:我用 C++ 创建了一个 QML 对象。在我的主要方法中,我可以设置我在自定义 QML 对象中定义的各种属性。从 main 方法设置时,各种属性按预期显示。当我从我的更新方法中设置属性时,显示永远不会更新。我已经验证了我的自定义 QML 对象中的关联方法正在接收我传递给它的值。为什么我的显示器不会更新?
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "horizontalBarGraph.h"
#include "speedometer.h"
#include "test.h"
#include <QTimer>
#include <QDebug>
//QObject *item = NULL;
static HorizontalBarGraph *ptrOilTemp = nullptr;
static int value = 0;
int update()
//qInfo() << "update() called.";
if(value > ptrOilTemp->getMaxValue())
value = 0;
ptrOilTemp->setActualValue(value);
qInfo() << "value = " << value;
value++;
//ptrOilTemp->setUnits("Test");
return 0;
int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<Speedometer>("com.ulasdikme.speedometer",1,0,"Speedometer");
qmlRegisterType<HorizontalBarGraph>("com.kubie.horizontalBarGraph", 1, 0, "HorizontalBarGraph");
qmlRegisterType<Test>("com.kubie.test", 1, 0, "Test");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
//item = engine.rootObjects().at(0)->findChild<QQuickItem*>("testing");
QObject *object = engine.rootObjects()[0];
QObject *oilTemp = object->findChild<QObject*>("oilTemp");
QObject *oilPressure = object->findChild<QObject*>("oilPressure");
QObject *coolantTemp = object->findChild<QObject*>("coolantTemp");
QObject *coolantPressure = object->findChild<QObject*>("coolantPressure");
QObject *intakeAirTemp = object->findChild<QObject*>("intakeAirTemp");
QObject *engineRPM = object->findChild<QObject*>("engineRPM");
//HorizontalBarGraph *ptrOilTemp = qobject_cast<HorizontalBarGraph*>(oilTemp);
ptrOilTemp = qobject_cast<HorizontalBarGraph*>(oilTemp);
HorizontalBarGraph *ptrOilPressure = qobject_cast<HorizontalBarGraph*>(oilPressure);
HorizontalBarGraph *ptrCoolantTemp = qobject_cast<HorizontalBarGraph*>(coolantTemp);
HorizontalBarGraph *ptrCoolantPressure = qobject_cast<HorizontalBarGraph*>(coolantPressure);
HorizontalBarGraph *ptrIntakeAirTemp = qobject_cast<HorizontalBarGraph*>(intakeAirTemp);
HorizontalBarGraph *ptrEngineRPM = qobject_cast<HorizontalBarGraph*>(engineRPM);
qreal val1 = 0;
//qreal val2 = 25;
qreal val3 = 100;
QString degF(QChar(0x00b0));
degF += "F";
ptrOilTemp->setSensorName("Oil Temp");
ptrOilTemp->setUnits(degF);
ptrOilTemp->setMinValue(val1);
ptrOilTemp->setMaxValue(val3);
//ptrOilTemp->setActualValue(val2);
ptrOilPressure->setSensorName("Oil Press");
ptrOilPressure->setUnits("PSI");
ptrCoolantTemp->setSensorName("Coolant Temp");
ptrCoolantTemp->setUnits(degF);
ptrCoolantPressure->setSensorName("Coolant Press");
ptrCoolantPressure->setUnits("PSI");
ptrIntakeAirTemp->setSensorName("Intake Air Temp");
ptrIntakeAirTemp->setUnits(degF);
ptrEngineRPM->setSensorName("");
ptrEngineRPM->setUnits("RPM");
qInfo() << "Initializing timer.";
QTimer timer;// = new QTimer(this);
QObject::connect(&timer, &QTimer::timeout, update);
timer.start(100);
return app.exec();
horizontalBarGraph.cpp
#include <QPainter>
#include "horizontalBarGraph.h"
HorizontalBarGraph::HorizontalBarGraph(QQuickItem *parent)
:QQuickPaintedItem(parent),
_horizontalBarGraphWidth(260),
_horizontalBarGraphHeight(75),
_minValue(0),
_maxValue(0),
_actualValue(0),
_sensorName("Sensor Name"),
_units("Units")
void HorizontalBarGraph::paint(QPainter *painter)
QRectF rect = this->boundingRect();
painter->setRenderHint(QPainter::Antialiasing);
QPen pen = painter->pen();
pen.setCapStyle(Qt::FlatCap);
QFont bottomFont("Arial", 14, QFont::Bold);
QFont topFont("Arial", 16, QFont::Bold);
QColor gray1(225, 225, 225);
QColor gray2(200, 200, 200);
QColor gray3(175, 175, 175);
QColor gray4(100, 100, 100);
//minValue, actualValue, maxValue
painter->save();
painter->setFont(bottomFont);
pen.setColor(gray1);
painter->setPen(pen);
painter->drawText(rect.adjusted(0, 50, -210, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_minValue), 'f', 0)); //Draws minValue
painter->drawText(rect.adjusted(210, 50, 0, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_maxValue), 'f', 0)); //Draws maxValue
painter->drawText(rect.adjusted(0, 50, 0, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_actualValue), 'f', 1));
//pen.setStyle(Qt::DotLine); //Next 3 lines were used to show the bounding rectangle for a drawText object
//painter->setPen(pen);
//painter->drawRect(rect.adjusted(0, 50, -150, 0));
painter->restore();
//Bar chart background
painter->save();
painter->fillRect(rect.adjusted(25, 35, -25, -25), gray1);
painter->restore();
//Lo
painter->save();
painter->fillRect(rect.adjusted(25, 35, -185, -25), gray2);
painter->restore();
//LoLo
painter->save();
painter->fillRect(rect.adjusted(25, 35, -210, -25), gray3);
painter->restore();
//Hi
painter->save();
painter->fillRect(rect.adjusted(185, 35, -25, -25), gray2);
painter->restore();
//HiHi
painter->save();
painter->fillRect(rect.adjusted(210, 35, -25, -25), gray3);
painter->restore();
//Sensor name, Units
painter->save();
painter->setFont(topFont);
pen.setColor(gray1);
painter->setPen(pen);
painter->drawText(rect.adjusted(25, 0, -50, -40), Qt::AlignLeft | Qt::AlignTop, _sensorName); //Draws sensor name
painter->drawText(rect.adjusted(50, 0, -25, -40), Qt::AlignRight | Qt::AlignTop, _units); //Draws units
painter->restore();
//Arrow
// painter->save();
// static const QPointF points[3] =
// QPointF(17.5, 27.5),
// QPointF(32.5, 27.5),
// QPointF(25.0, 42.5)
// ;
// painter->drawPolygon(points, 3);
// painter->restore();
painter->save();
QPainterPath path;
qreal x = scale(_actualValue, _minValue, _maxValue, 25, 235);
//path.moveTo(17.5, 27.5);
//path.lineTo(32.5, 27.5);
//path.lineTo(25.0, 42.5);
path.moveTo(x - 7.5, 27.5);
path.lineTo(x + 7.5, 27.5);
path.lineTo(x, 42.5);
path.closeSubpath();
painter->fillPath(path, gray4);
painter->restore();
qreal HorizontalBarGraph::getHorizontalBarGraphWidth()
return _horizontalBarGraphWidth;
qreal HorizontalBarGraph::getHorizontalBarGraphHeight()
return _horizontalBarGraphHeight;
qreal HorizontalBarGraph::getMinValue()
return _minValue;
qreal HorizontalBarGraph::getMaxValue()
return _maxValue;
qreal HorizontalBarGraph::getActualValue()
return _actualValue;
QString HorizontalBarGraph::getSensorName()
return _sensorName;
QString HorizontalBarGraph::getUnits()
return _units;
void HorizontalBarGraph::setHorizontalBarGraphWidth(qreal width)
if(_horizontalBarGraphWidth == width)
return;
_horizontalBarGraphWidth = width;
emit widthChanged();
void HorizontalBarGraph::setHorizontalBarGraphHeight(qreal height)
if(_horizontalBarGraphHeight == height)
return;
_horizontalBarGraphHeight = height;
emit heightChanged();
void HorizontalBarGraph::setMinValue(qreal minValue)
if(_minValue == minValue)
return;
_minValue = minValue;
emit minValueChanged();
void HorizontalBarGraph::setMaxValue(qreal maxValue)
if(_maxValue == maxValue)
return;
_maxValue = maxValue;
emit maxValueChanged();
void HorizontalBarGraph::setActualValue(qreal actualValue)
if(_actualValue == actualValue)
return;
_actualValue = actualValue;
emit actualValueChanged();
void HorizontalBarGraph::setSensorName(QString sensorName)
if(_sensorName == sensorName)
return;
_sensorName = sensorName;
emit sensorNameChanged();
void HorizontalBarGraph::setUnits(QString units)
if(_units == units)
return;
_units = units;
emit unitsChanged();
qreal HorizontalBarGraph::scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax)
qreal output = (outputMax - outputMin) * (input - inputMin) / (inputMax - inputMin) + outputMin;
if(output > outputMax)
output = outputMax;
if(output < outputMin)
output = outputMin;
return output;
horizontalBarGraph.h
#ifndef HORIZONTALBARGRAPH_H
#define HORIZONTALBARGRAPH_H
#include <QObject>
#include <QQuickPaintedItem>
class HorizontalBarGraph : public QQuickPaintedItem
Q_OBJECT
Q_PROPERTY(qreal horizontalBarGraphWidth READ getHorizontalBarGraphWidth WRITE setHorizontalBarGraphWidth NOTIFY horizontalBarGraphWidthChanged)
Q_PROPERTY(qreal horizontalBarGraphHeight READ getHorizontalBarGraphHeight WRITE setHorizontalBarGraphHeight NOTIFY horizontalBarGraphHeightChanged)
Q_PROPERTY(qreal minValue READ getMinValue WRITE setMinValue NOTIFY minValueChanged)
Q_PROPERTY(qreal maxValue READ getMaxValue WRITE setMaxValue NOTIFY maxValueChanged)
Q_PROPERTY(qreal actualValue READ getActualValue WRITE setActualValue NOTIFY actualValueChanged)
Q_PROPERTY(QString sensorName READ getSensorName WRITE setSensorName NOTIFY sensorNameChanged)
Q_PROPERTY(QString units READ getUnits WRITE setUnits NOTIFY unitsChanged)
public:
HorizontalBarGraph(QQuickItem *parent = 0);
virtual void paint(QPainter *painter);
qreal getHorizontalBarGraphWidth();
qreal getHorizontalBarGraphHeight();
qreal getMinValue();
qreal getMaxValue();
qreal getActualValue();
QString getSensorName();
QString getUnits();
void setHorizontalBarGraphWidth(qreal width);
void setHorizontalBarGraphHeight(qreal height);
void setMinValue(qreal minValue);
void setMaxValue(qreal maxValue);
void setActualValue(qreal actualValue);
void setSensorName(QString sensorName);
void setUnits(QString units);
signals:
void horizontalBarGraphWidthChanged();
void horizontalBarGraphHeightChanged();
void minValueChanged();
void maxValueChanged();
void actualValueChanged();
void sensorNameChanged();
void unitsChanged();
private:
qreal _horizontalBarGraphWidth;
qreal _horizontalBarGraphHeight;
qreal _minValue;
qreal _maxValue;
qreal _actualValue;
QString _sensorName;
QString _units;
qreal scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax);
;
#endif // HORIZONTALBARGRAPH_H
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
import com.kubie.horizontalBarGraph 1.0
Window
id: window
visible: true
width: 800
height: 480
title: qsTr("REDNEKSLDHLR")
color: "black"
// Rectangle
//
// width: 260
// height: 75
// color: "#7a0505"
// anchors.bottom: parent.bottom
// anchors.bottomMargin: 0
// anchors.left: parent.left
// anchors.leftMargin: 0
//
HorizontalBarGraph
objectName: "oilTemp"
anchors.left: parent.left
anchors.leftMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
HorizontalBarGraph
objectName: "oilPressure"
anchors.left: parent.left
anchors.leftMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 75
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
HorizontalBarGraph
objectName: "coolantTemp"
anchors.right: parent.right
anchors.rightMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
HorizontalBarGraph
objectName: "coolantPressure"
anchors.right: parent.right
anchors.rightMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 75
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
HorizontalBarGraph
objectName: "intakeAirTemp"
anchors.left: parent.left
anchors.leftMargin: parent.width / 2 - width / 2;
anchors.bottom: parent.bottom
anchors.bottomMargin: 0
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
HorizontalBarGraph
objectName: "engineRPM"
anchors.left: parent.left
anchors.leftMargin: parent.width / 2 - width / 2;
anchors.bottom: parent.bottom
anchors.bottomMargin: 75
width: horizontalBarGraphWidth
height: horizontalBarGraphHeight
【问题讨论】:
请提供minimal reproducible example。 QGuiApplication 在哪里? @eyllanesc 帖子已更新为包含所有代码。 就是这样......我遵循的示例从未称为更新 - 我认为这有点奇怪。我从来没有把两个和两个放在一起。您可以发布作为答案,我会接受吗? 【参考方案1】:您必须使用update()
方法来重新绘制GUI,因此每次修改用于绘制的属性时都必须调用它。举例:
void HorizontalBarGraph::setActualValue(qreal actualValue)
if(_actualValue == actualValue)
return;
_actualValue = actualValue;
update();
emit actualValueChanged();
【讨论】:
以上是关于QML 对象不更新显示的主要内容,如果未能解决你的问题,请参考以下文章
在 QML 中为 MapQuickItem 设置位置更新动画