gpt4 book ai didi

c++ - 将 C++ 信号发送到 QML

转载 作者:行者123 更新时间:2023-11-28 05:21:02 27 4
gpt4 key购买 nike

我有一个可通过 WiringPiI2C 获得的 int来自 ADC 的最大速率为每秒 680 次。我想以 200-500Hz 的频率定期采样并转发该值到各种 GUI 对象。我尝试了几种将 C++ 数据类型导入 QML 的策略,但我似乎总是做得不够。

我使用自定义 Handler 类和 Q_PROPERTY 接近成功了。宏,但该值只出现一次;它不会在屏幕上更新。我可以使用 myData 调用数据在 QML(console.log) 中整天上课,或者直接从 C++ 中的采集函数 (qDebug) 中上课,它完美地更新了——我可以看到 ADC 的模拟输入电压变化很小的值。每次我运行程序时,屏幕上显示的单个卡住值都与上次不同,因此必须将真实数据显示在屏幕上。但是为什么不更新呢?

我是否必须以某种方式运行emit pressureChanged线指向 AppEngineengine.rootContext()->setContextProperty("myData",myData.data());与 DataHandler 的相同实例?我该怎么做?

更新 确实,emit行和 AppEngine 指针必须在 DataHandler 的同一实例内.但是我看不到如何在一个实例中同时做到这两点。似乎有些东西总是超出范围。我尝试运行 emit通过 main.qml 中的 QTimer它有效,但表现非常糟糕。我需要比 5-6Hz 更快的刷新率,这大大减慢了 GUI 的其余功能。任何帮助获得 myData类(class) pressureChanged以 60+ Hz 的频率发送到 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几乎可以帮助我理解发生了什么,我怀疑我的问题与那里所说的密切相关:也就是说,不知何故我的绑定(bind)无效,因此只调用函数 DataHandler::getPressure 1次。

我尝试关注 this tutorial ,但这是一种不同的情况(从 C++ 在 QML 中创建一个类对象,我只想将 1 种数据类型移动到 QML),所以我没有足够的能力将它很好地应用于我的问题......

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

数据处理程序.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

重要的部分
数据处理程序.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()
}
}
}

额外信息
正如你在上面看到的,我创建了一个 PI_THREAD不断调用 publishPressure函数,这只是我从课外发出信号的方式。我想我可以以某种方式使用 QTimer或其他方法,如果这就是搞砸了。

我用了 qDebug()证明 PI_THREAD 确实在调用 publishPressure为了理智起见,定期将其减慢到 500 毫秒。我知道 C++ 数据采集是成功的,因为我看到它以 500Hz 的频率将数据输出到控制台。我知道已经达到了发射功能,但也许它没有被执行?

我还发现,带有 Keys 类的 QML 绑定(bind)在 Window 中运行良好,但 非常奇怪。不是 MainForm .我想知道这是否以某种方式解决了问题

最佳答案

我马上就发现了一些问题:

  • 当你调用 setupPressure 时,你是在一个临时对象上这样做的。即使它有效,我怀疑这就是你想要做的。
  • 您创建另外两个 DataHandler(一个在 main 中,您正确设置(尽管为时已晚)作为 QML 的上下文属性。另一个在您的 PI_THREAD... 中创建,然后您对其进行操作。这不是 QML 注册的对象.
  • 您还将字符串 QML 属性 (Text.text) 绑定(bind)到 int C++ Q_PROPERTY。我不确定这是否正常工作。无论如何,我建议尝试更好地匹配类型。

  • 解决这些问题,你就会上路。

    关于c++ - 将 C++ 信号发送到 QML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41499886/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com