首页 > 解决方案 > QML 程序中的自动开/关(在 Qt 中创建)

问题描述

我刚刚为我在 Qt 5.14.2 中为树莓派创建的应用程序创建了手动转向。这是一个简单的 HMI,几乎没有可以设置的温度选项。它还显示了连接到 GPIO 的一些简单数字传感器的实际温度。还有一个连接的继电器,可以通过单击触摸屏上的按钮手动打开和关闭。我设法为主面板上的文本创建温度显示的自动刷新设置:

main.cpp: item->setProperty("text",QString().setNum(t,'f',1)); 并且也在同一个文件中,在int mainitem = engine.rootObjects().at(0)->findChild<QQuickItem*>("temp");

和 main.qml 文件的简单文本:

Text {
        id: temp
        objectName: "temp"
        x: 25
        y: 167
        width: 190
        height: 105
        color: "#33bc00"
        text: qsTr("10.0")
        font.family: "Arial"
        font.pixelSize: 90
    }

当然,还可以通过将 c++ 类(用于 WiringPi)添加到项目中,然后在 qml 中实现所有内容来手动控制:

            Button{
                id: buttonRelay1on
                text: '  Relay On '
                palette {
                          button: "#33bc00"
                      }
                onClicked: {
                    output21.pinLow();
                }
            }

我在 qml 中还有另一个文本字段来显示所需的温度(可以通过单击 4 个按钮之一来更改)。

问题:实现该继电器自动转向的最简单方法是什么?

我想创建一个简单的条件:

我试图通过在 main.cpp 中创建条件来做到这一点,但 getNumber/getText 选项不起作用......仅用于发送数据,就像我对温度传感器所做的那样:

item->setProperty("text",QString().setNum(t,'f',1)); 我还在 qml/qt 中搜索了示例条件,但我找不到任何对我的问题和我的知识水平来说合理的东西......

标签: c++qtautomationqml

解决方案


您不必从 C++ 访问 QML 元素,反之亦然,在以下简单示例中,传感器是映射到 qproperty 的 QObject,然后 QML 中的条件更简单:

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15


Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    QtObject{
        id: internals
        property real threshold_temperature: 0
    }

    GridLayout {
        id: grid
        anchors.fill: parent
        columns: 2
        Text { text: "Current Temperature:"; font.bold: true}
        Text { text: Number(sensor.value).toLocaleString(Qt.locale("en_US"), "f", 1)}
        Text { text: "Threshold Temperature:"; font.bold: true}
        Text { text: Number(internals.threshold_temperature).toLocaleString(Qt.locale("en_US"), "f", 1) }
        Text { text: "State:"; font.bold: true}
        Text { text: sensor.value > internals.threshold_temperature ? "Relay On" : "Relay Off"}
    }
    Component.onCompleted: internals.threshold_temperature = 20
}

主文件

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include <QTimer>
#include <QRandomGenerator>


class Sensor: public QObject{
    Q_OBJECT
    Q_PROPERTY(qreal value READ value NOTIFY valueChanged)
public:
    Sensor(QObject *parent=nullptr):QObject(parent), m_value(0)
    {}
    qreal value() const{
        return m_value;
    }
    void updateValue(qreal value){
        m_value = value;
        Q_EMIT valueChanged();
    }
signals:
    void valueChanged();
private:
    qreal m_value;
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    Sensor sensor;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("sensor", &sensor);
    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);

    // emulate temperature
    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, [&sensor](){
        qreal temperature = QRandomGenerator::global()->bounded(50.0);
        sensor.updateValue(temperature);
    });
    timer.start(1000);

    return app.exec();
}

#include "main.moc"

推荐阅读