将 QML 属性 链接到 QSerial 输出

Linking a QML Property to QSerial Output

我正在使用 Qt 教程创建仪表集群。我已经完成了所有这些步骤并完成了视觉方面的工作,所以现在我在编码方面并且完全是绿色的。

设置是 Arduino 向 Raspberry Pi 发送数据。我正在尝试获取该数据并将其发送到我的 QML 以更新 QML 中的 'rpmFrame'。作为实验,我让 Arduino 只发送“800”,但我无法让仪表以任何容量显示它(数据完美无缺,我已将其分配给双 'rpmDouble'。)我有几次尝试获得 incoming:: valueToQML 以在调试中显示 800,但它从未转换为 QML。我认为我对所有变量如何在 header 等

中工作的基本理解很差

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Timeline 1.0
import incoming 1.0

Window {
    width: 1280
    height: 480
    visible: true
    color: "#FFFFFF"

SerialIncoming{
        id:incoming
}
    Rectangle {
        id: rectangle
        x: 0
        y: -7
        width: 1280
        height: 487
        color: "#ffffff"
    }

        Rectangle {
            id: oil
            x: 331
            y: 52
            width: 69
            height: 47
            color: "#ff0000"
        }

        Rectangle {
            id: battery
            x: 405
            y: 52
            width: 74
            height: 47
            color: "#ff0000"
        }

        Rectangle {
            id: leftturn
            x: 360
            y: 105
            width: 69
            height: 47
            color: "#15ff0d"
        }

        Rectangle {
            id: hibeam
            x: 807
            y: 65
            width: 69
            height: 47
            color: "#00caff"
        }

        Rectangle {
            id: brake
            x: 881
            y: 64
            width: 74
            height: 47
            color: "#ff0000"
        }

        Rectangle {
            id: rightturn
            x: 852
            y: 117
            width: 69
            height: 47
            color: "#15ff0d"
        }

        Rectangle {
            id: oil1
            x: 369
            y: 386
            width: 69
            height: 47
            color: "#ff0000"
        }

    Tachometer {
        id: tachometer
        x: 423
        y: 27
        rpmFrame: {incoming.valueToQML} // <-- this is where serial data goes
        displaySpeed: "500"
        scale: 0.9

    }




}

incoming.cpp

incoming::incoming(QObject *parent) : QObject(parent) {

    arduino = new QSerialPort(this);
    serialBuffer="";

    arduino->setPortName("ttyACM0");
    arduino->setBaudRate (QSerialPort::Baud9600);
    arduino->setDataBits (QSerialPort::Data8);
    arduino->setParity(QSerialPort::NoParity);
    arduino->setStopBits(QSerialPort::OneStop);
    arduino->setFlowControl (QSerialPort::NoFlowControl);
    arduino->open(QSerialPort::ReadOnly);
    QObject::connect(arduino, SIGNAL(readyRead()), this, SLOT(readSerial()));
    qDebug() << "KenDash v0.0";


}

void incoming::readSerial()
{
    //Buffer to Filter Data
    if(arduino->bytesAvailable()>0||arduino->waitForReadyRead(10))
    {
    QStringList bufferSplit = serialBuffer.split(",");

    if(bufferSplit.length() < 5)
        {
    QByteArray serialData = arduino->readAll();
    serialBuffer += QString::fromStdString(serialData.toStdString());
    serialData.clear();
        }else{
    //Clean Data Output
    serialBuffer="";
    QString serialOutput = bufferSplit[1];

    //Split the Clean Data To Sections
    QStringList dataSplit = bufferSplit[1].split("/");
    QString rpmOutput = dataSplit[0];
    QString speedOutput = dataSplit[1];

    //qDebug() << "RPM:" << rpmOutput << "Speed:" << speedOutput;

    rpmDouble = rpmOutput.toDouble();


    incoming *myinstance = new incoming;
    QObject *object = myinstance;

   object->setProperty("valueToQML", rpmDouble);
   //Read Data in Debug Panel
   qDebug() << "RPM(onheader2):" << incoming::valueToQML();
        }
    }



}

main.cpp

        #include "incoming.h"
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
        qmlRegisterType<incoming>("incoming", 1, 0, "SerialIncoming");
        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);
        void incomingserial();
        return app.exec();
    
    }

incoming.h

  #ifndef INCOMING_H
#define INCOMING_H

#pragma once
#include <QString>
#include <QSerialPort>
#include <QDebug>
#include <QObject>
#include <iostream>


void incomingserial();

class incoming : public QObject
{
    Q_OBJECT
    Q_PROPERTY(double valueToQML READ valueToQML WRITE setValuetoQML NOTIFY valueToQMLChanged)

public:

    explicit incoming(QObject *parent = 0);
    //~incoming();
    double valueToQML() const
    { return rpmDouble;}
    void setValuetoQML(double valueToQML)
    {
        _valueString = valueToQML;
        emit valueToQMLChanged(valueToQML);
    }


signals:
    void valueToQMLChanged(double);

private slots:
        void readSerial();

private:
    double _valueString;
    QSerialPort *arduino;
    static const quint16 arduino_uno_vendor_id = 9025;
    static const quint16 arduino_uno_product_id = 67;
    QByteArray serialData;
    QString serialBuffer;
    QString parsed_data;
    double rpmTachOutput;
    double rpmDouble;
    QString rpmOutput;
    double rpmToDisplay();

};




#endif // INCOMING_H

我不明白为什么你将新的传入值设置为 _valueString 但你从 rpmDouble 读取值。您的 QProperty 读写函数应该引用相同的变量,因此当某些内容来自串行时,您应该调用:

this->setValuetoQML(rpmOutput.toDouble());

并在 setValuetoQML 函数中像这样分配新值:

rpmDouble = valueToQML;

因为当调用 valueToQML() 时,您将返回 rpmDouble