簡體   English   中英

從C ++更改QML對象值

[英]Changing QML Object value from C++

我創建了一個QML類,例如

import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

Rectangle {
    width: 80
    height: 200
    property double myVal: 15

    Timer {
        running: true
        repeat: true
        interval: 1
        onTriggered: gauge.value = myVal
    }

    Gauge {
        objectName: "gauge"
        id: gauge
        anchors.fill: parent
        anchors.margins: 10

        value: myVal
        Behavior on value {
            NumberAnimation {
                duration: 1000
            }
        }

        style: GaugeStyle {
            valueBar: Rectangle {
                implicitWidth: 16
                color: Qt.rgba(gauge.value / gauge.maximumValue, 0, 1 - gauge.value / gauge.maximumValue, 1)
            }
        }
    }
}

我想從我的c ++文件中更改值。 為此,我創建了一個setDataToGauge()方法,該方法類似於

void MainWindow::setDataToGauge(double newVal){

    QQmlApplicationEngine engine;
    QQmlComponent component(&engine, QUrl::fromLocalFile("gauge.qml"));
    QObject object = component.create();
    QObject *myGauge = object->findChild<QObject*>("gauge");

    if(myGauge){
        myGauge->setProperty("value",newVal);
        qDebug() << myGauge->property("value");

    }

}

這個。 但是,它不會更改儀表的值。 我嘗試了不同的方法,但是找不到解決方案。 當我掉落

    Behavior on value {
        NumberAnimation {
            duration: 1000
        }
    }

來自QML文件值的這部分正在更改,但儀表視圖未更改。 另外,我正在添加我的c ++文件的完整代碼

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDateTime>
#include <QtQuickWidgets/QQuickWidget>
#include <QtQml>
#include <QObject>

QObject *object;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_serial(new QSerialPort(this))
{
    ui->setupUi(this);

    ui->gaugeWidget->setSource(QUrl::fromLocalFile("gauge.qml"));
    ui->gaugeWidget->setUpdatesEnabled(true);

    QQmlApplicationEngine engine;
    QQmlComponent component(&engine, QUrl::fromLocalFile("gauge.qml"));
    object = component.create();

    setDataToGauge(60.0);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setDataToGauge(double newVal){

    QObject *myGauge = object->findChild<QObject*>("gauge");

    if(myGauge){
        QQmlProperty::write(myGauge, "value", newVal);
        qDebug() << myGauge->property("value");
}

}

那里有什么問題?

在嘗試解決方案時,您正在創建另一個儀表,而該儀表沒有顯示,因為QQmlApplicationEngine是一個局部變量,在完成執行后將被刪除,此外, QQmlApplicationEngine需要一個WindowApplicationWindow ,而不是Rectangle類的Item

另一方面,建議使用qresource存儲.qml,因為否則,您每次編譯可執行文件的那一面都必須復制它們。

還不建議從C ++訪問QML對象,最好使用setContextProperty()將C ++對象導出到QML。

一個簡單的解決方案是創建一個信號,該信號通過Connections :: Connections

*。H

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void setDataToGauge(double newVal);
signals:
    void dataGaugeChanged(double dataToGauge); // signal
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

*的.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QQmlEngine>
#include <QQmlContext>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->gaugeWidget->engine()->rootContext()->setContextProperty("MainWindow", this);
    ui->gaugeWidget->setSource(QUrl("qrc:/gauge.qml"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setDataToGauge(double newVal){
    emit dataGaugeChanged(newVal);
}

gauge.qml

import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

Rectangle {
    width: 80
    height: 200

    Gauge {
        id: gauge
        anchors.fill: parent
        anchors.margins: 10

        Behavior on value {
            NumberAnimation {
                duration: 1000
            }
        }

        style: GaugeStyle {
            valueBar: Rectangle {
                implicitWidth: 16
                color: Qt.rgba(gauge.value / gauge.maximumValue, 0, 1 - gauge.value / gauge.maximumValue, 1)
            }
        }
    }
    Connections{
        target: MainWindow
        onDataGaugeChanged: gauge.value = dataToGauge
    }
}

另一種選擇是創建一個Q_PROPERTY並進行綁定:

*。H

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    Q_PROPERTY(double dataGauge READ dataGauge WRITE setDataGauge NOTIFY dataGaugeChanged)

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    double dataGauge() const;
    void setDataGauge(double dataGauge);
signals:
    void dataGaugeChanged();
private:
    Ui::MainWindow *ui;
    double mDataGauge;
};

#endif // MAINWINDOW_H

*的.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QQmlEngine>
#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->gaugeWidget->engine()->rootContext()->setContextProperty("MainWindow", this);
    ui->gaugeWidget->setSource(QUrl("qrc:/gauge.qml"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

double MainWindow::dataGauge() const
{
    return mDataGauge;
}

void MainWindow::setDataGauge(double dataGauge)
{
    if(mDataGauge == dataGauge)
        return;
    mDataGauge = dataGauge;
    emit dataGaugeChanged();
}

* .qml

import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

Rectangle {
    width: 80
    height: 200

    Gauge {
        id: gauge
        anchors.fill: parent
        anchors.margins: 10
        value: MainWindow.dataGauge // binding

        Behavior on value {
            NumberAnimation {
                duration: 1000
            }
        }

        style: GaugeStyle {
            valueBar: Rectangle {
                implicitWidth: 16
                color: Qt.rgba(gauge.value / gauge.maximumValue, 0, 1 - gauge.value / gauge.maximumValue, 1)
            }
        }
    }
}

可以在以下鏈接中找到這兩種解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM