首页 文章

将C信号发送到QML

提问于
浏览
0

我通过 WiringPiI2C 从ADC获得一个int,最大速率为每秒680次 . 我已经尝试了一些将C数据类型转换为QML的策略,而且我似乎总是很短 .

我接近成功使用自定义Handler类和 Q_PROPERTY 宏,但该值只出现一次;它不会在屏幕上更新 . 我可以整天使用 myData 类在QML(console.log)中调用数据,或者直接从C( qDebug )中的采集函数调用数据并且它可以完美地更新 - 我可以将值视为ADC 's analog input voltage varies ever-so-slightly. Every time I run the program, the single frozen value that shows on my screen is different than the last, thus real data must be making it to the screen. But why doesn'更新吗?

我是否必须以相同的DataHandler实例运行 emit pressureChangedand 指向AppEngine engine.rootContext()->setContextProperty("myData",myData.data()); ?我该怎么做?

UPDATE 实际上, emit 行和AppEngine指针必须位于 DataHandler 的同一实例中 . 但我没有看到我如何用一个实例做两件事 . 似乎有些东西总是超出范围 . 我尝试在 main.qml 中通过QTimer运行 emit 并且它可以工作,但它执行得非常糟糕 . 我需要比5-6Hz更快的刷新率,并且它大大减慢了其余的GUI功能 . 有什么帮助让 myData 类的 pressureChanged 信号以60赫兹的频率发送到QML?

应用输出

qrc:/main.qml:31: ReferenceError: myData is not defined

qrc:/main.qml:31: ReferenceError: myData is not defined

I'm sampling, why isn't anyone getting this???

I'm sampling, why isn't anyone getting this???

25771

I'm sampling, why isn't anyone getting this???

25686

I'm sampling, why isn't anyone getting this???

25752

I'm sampling, why isn't anyone getting this???

qml: 25763                    <--- this is a manual button push on screen

I'm sampling, why isn't anyone getting this???

qml: 25702                    <--- this is a manual button push on screen

I'm sampling, why isn't anyone getting this???

25751

为什么QML允许我使用 myData 将数据发送到控制台,但是不允许我使用 myData 作为操作QML对象的属性?

有没有更容易的方法来获取简单的数据类型(在我的情况下,我将有两个整数)到QML不断更新屏幕上的各种文本对象?

This post接近帮助我理解's going on, and I suspect my problem is closely related to what'在那里说了什么:就是说,我的绑定无论如何都是无效的,因此只调用函数 DataHandler::getPressure 一次 .

我试过跟随this tutorial,但是它足够能够很好地应用于我的问题......

我已经尝试了好几天了...实例化 myData 的3种方法,尝试使用/不使用 QScopedPointer ,尝试了各种方式在QML中访问 myData ...我想出去了,请帮忙!我呼吁StackOverflow的众神,因为我的堆栈真的溢出无知......

datahandler.h

#ifndef DATAHANDLER_H
#define DATAHANDLER_H

#include <QObject>
#include <QPoint>
#include <QDebug>

class DataHandler : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int pressure READ getPressure NOTIFY pressureChanged)

public:
    explicit DataHandler(QObject *parent = 0);

    void setupPressure();
    int getPressureSample();
    int getPressure();
    void publishPressure();

signals:
    void pressureChanged();

};

#endif // DATAHANDLER_H

datahandler.cpp的重要部分

#include <wiringPi.h>
#include <wiringPiI2C.h>
#include "datahandler.h"

#define SAMPLES 10

DataHandler::DataHandler(QObject *parent) : QObject(parent)
{

}

int DataHandler::getPressure() {
    int totalSum = 0;
    for (int i = 0; i < SAMPLES; i++){
        totalSum += getPressureSample();
        delay(5);    // Sampling at ~200Hz, the ADC itself maxes at 680Hz so don't sample faster than that.
    }
    qDebug() << "I'm sampling, why isn't anyone getting this update???";
    return totalSum/SAMPLES;
}

void DataHandler::publishPressure() {
    emit pressureChanged();
}

main.cpp的重要部分

#include <QCursor>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include "functions.h"
#include "datahandler.h"

PI_THREAD(updatePressure)
{
    DataHandler pressureData(new DataHandler);
    while (true){
        delay(500);
        pressureData.publishPressure();
        qDebug() << pressureData.getPressure();
    }
}

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    wiringPiSetup();
    DataHandler().setupPressure();

    app.setOverrideCursor( QCursor( Qt::BlankCursor ) );    //Hide the cursor, no one needs that thing showing!

    QScopedPointer<Functions> myFunctions(new Functions);
    QScopedPointer<DataHandler> myData(new DataHandler);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    engine.rootContext()->setContextProperty("myFunctions",myFunctions.data());
    engine.rootContext()->setContextProperty("myData",myData.data());

    piThreadCreate(updatePressure);

    return app.exec();
}

main.qml的重要部分

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4

//DECLARATIVE CONTENT
Window {
    id: myWindow
    visible: true
    width: 800
    height: 480
    title: qsTr("Hello World")
    Item {
        focus: true
        Keys.onEscapePressed: myWindow.close()
        Keys.onSpacePressed: console.log("HOW?")
    }

    MainForm {
        id: root
        anchors.fill: parent
        property var shiftArray: 0
        property var tumblerArray: noteSelector.array

        Text {
            id: testText
            z: 9
            anchors.fill: parent
            color: "#FF0000"
            text: myData.pressure
        }

        customPressureClick.onClicked: {
            console.log(myData.pressure)
            toggleCustomPressureState()
            attemptCustomPressure()
        }
    }
}

EXTRA INFO 如上所示,我创建了一个 PI_THREAD 来不断调用 publishPressure 函数,这只是我从课外发出信号的方式 . 我想我可以某种方式使用 QTimer 或其他一些方法,如果's what' s搞砸了 .

我使用 qDebug() 来证明PI_THREAD确实经常调用 publishPressure ,为了理智而将其减慢到500ms . 我知道C数据采集是成功的,因为我看到它以500Hz的频率输出数据到控制台 . 我知道已经达到了emit函数,但是它可能以某种方式没有被执行?

我还发现很奇怪,使用Keys类的QML绑定在Window中运行良好,但在 MainFormnot . 我想知道是否以某种方式解决了这个问题

1 回答

  • 1

    我发现的一些问题:

    • 当您调用setupPressure时,您会在临时对象上执行此操作 . 即使它有效,我怀疑这是你想要做的 .

    • 你创建另外两个DataHandler(一个在main中,你正确设置(虽然为时已晚)作为QML的上下文属性 . 另一个你在PI_THREAD ...中创建的东西,然后你可以操作 . 这不是QML的对象注册 .

    • 您还将字符串QML属性(Text.text)绑定到int C Q_PROPERTY . 我不确定这是否正常 . 无论如何,我建议尝试更好地匹配类型 .

    解决这些问题,你就可以了 .

相关问题