如何从 UART 获取二维数组到 QList<QString> Qt 并在 QML 上设置文本
How to get 2D array from UART to QList<QString> Qt and set text on QML
我从 Arduino 发送的 UART 接收到二维数组。
我可以在调试中显示它,但我不能将它保存在 QList 变体中以在 QML 中设置矩形矩阵的文本。
我想在 QML 的每个矩形上显示文本。
我该怎么办?
这是Arduino代码。我发送二维数组 17x17
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
analogWrite(LED_BUILTIN,255);
Serial.begin(115200);
void loop(){
double data[17][17];
if(Serial.available()){
delay(100);
for(int i=0; i<17; i++){
for(int j=0; j<17; j++){
data[i][j] = i+j+0.01;
sendData(data[i][j]);
delay(10);
}
}
}
return;
}
void sendData(double data){
Serial.print((data));
}
这是 readSerial 函数:
void serial::readSerial(){
serialData = arduino.readAll();
qDebug()<< serialData <<"\n";
}
QML 文件:
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 17*square_size
height: 17*square_size
title: qsTr("Hello World")
property int square_size: 30
Grid {
id: grid
columns: 17
Repeater{
id: rpt
model: 17*17
Rectangle{
width: square_size
height: square_size
border.color: "black"
border.width: 1
Text {
anchors.centerIn: parent
text: Serial.model_data[index]
}
}
}
}
}
serial.h:
#include <QQmlApplicationEngine>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QtDebug>
class serial: public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QString> text READ text NOTIFY textChanged)
public:
explicit serial(QQmlApplicationEngine *engine, QObject *parent = nullptr);
~serial();
void setupSerial();
Q_INVOKABLE QList<QString> text(){
return m_text;
}
private slots:
void readSerial();
private:
QQmlApplicationEngine* m_engine;
/* Varian of Arduino*/
QSerialPort arduino;
bool arduino_is_avaiable;
QString portName;
QByteArray serialData;
/*Varian of text*/
QList<QString> m_text;
signals:
void textChanged();
public slots:
};
#endif // SERIAL_H
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "serial.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
serial myserial(&engine);
engine.rootContext()->setContextProperty("Serial", &myserial);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
我认为您缺少 Serial
class 上的 属性 来读取数据:text: Serial.model_data[index]
。在屏幕上显示内容的最快解决方案是添加 属性 并按如下方式填写:
Serial.h(我遗漏了一些部分)
class Serial : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList model_data READ model_data NOTIFY modelDataChanged)
public:
explicit Serial(QObject *parent = nullptr);
QVariantList model_data() const { return model_data_; }
signals:
void modelDataChanged();
private slots:
void readSerial();
private:
QVariantList model_data_;
};
readSerial()
函数如下所示:
void Serial::readSerial()
{
QByteArray serialData = QByteArray(17 * 17 * 8, 0); //shortcut for testing
double *arr = reinterpret_cast<double*>(serialData.data());
model_data_.clear();
for(int i=0;i<17*17;i++)
{
model_data_.append(arr[i]);
}
emit modelDataChanged();
}
发生的情况是 QVariant 列表中充满了双精度值,这些双精度值已从字节重新解释为双精度值。请注意,每次 serialData
更改时都必须执行此操作。
但是,如果您想进一步了解,这可能并不理想。更改维度时,此设置将在 arduino 发送端、arduino 读取端和 qml 端失败。您应该考虑发送数组的维度,读取这些维度并对其进行操作。一个想法可能是QAbstractListModel,它已经有了rows/columns的概念;另一个更简单的想法可能是向 Serial
class 添加属性,说明尺寸(在 readSerial()
中读取)
我从 Arduino 发送的 UART 接收到二维数组。 我可以在调试中显示它,但我不能将它保存在 QList 变体中以在 QML 中设置矩形矩阵的文本。
我想在 QML 的每个矩形上显示文本。
我该怎么办?
这是Arduino代码。我发送二维数组 17x17
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
analogWrite(LED_BUILTIN,255);
Serial.begin(115200);
void loop(){
double data[17][17];
if(Serial.available()){
delay(100);
for(int i=0; i<17; i++){
for(int j=0; j<17; j++){
data[i][j] = i+j+0.01;
sendData(data[i][j]);
delay(10);
}
}
}
return;
}
void sendData(double data){
Serial.print((data));
}
这是 readSerial 函数:
void serial::readSerial(){
serialData = arduino.readAll();
qDebug()<< serialData <<"\n";
}
QML 文件:
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 17*square_size
height: 17*square_size
title: qsTr("Hello World")
property int square_size: 30
Grid {
id: grid
columns: 17
Repeater{
id: rpt
model: 17*17
Rectangle{
width: square_size
height: square_size
border.color: "black"
border.width: 1
Text {
anchors.centerIn: parent
text: Serial.model_data[index]
}
}
}
}
}
serial.h:
#include <QQmlApplicationEngine>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QtDebug>
class serial: public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QString> text READ text NOTIFY textChanged)
public:
explicit serial(QQmlApplicationEngine *engine, QObject *parent = nullptr);
~serial();
void setupSerial();
Q_INVOKABLE QList<QString> text(){
return m_text;
}
private slots:
void readSerial();
private:
QQmlApplicationEngine* m_engine;
/* Varian of Arduino*/
QSerialPort arduino;
bool arduino_is_avaiable;
QString portName;
QByteArray serialData;
/*Varian of text*/
QList<QString> m_text;
signals:
void textChanged();
public slots:
};
#endif // SERIAL_H
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "serial.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
serial myserial(&engine);
engine.rootContext()->setContextProperty("Serial", &myserial);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
我认为您缺少 Serial
class 上的 属性 来读取数据:text: Serial.model_data[index]
。在屏幕上显示内容的最快解决方案是添加 属性 并按如下方式填写:
Serial.h(我遗漏了一些部分)
class Serial : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList model_data READ model_data NOTIFY modelDataChanged)
public:
explicit Serial(QObject *parent = nullptr);
QVariantList model_data() const { return model_data_; }
signals:
void modelDataChanged();
private slots:
void readSerial();
private:
QVariantList model_data_;
};
readSerial()
函数如下所示:
void Serial::readSerial()
{
QByteArray serialData = QByteArray(17 * 17 * 8, 0); //shortcut for testing
double *arr = reinterpret_cast<double*>(serialData.data());
model_data_.clear();
for(int i=0;i<17*17;i++)
{
model_data_.append(arr[i]);
}
emit modelDataChanged();
}
发生的情况是 QVariant 列表中充满了双精度值,这些双精度值已从字节重新解释为双精度值。请注意,每次 serialData
更改时都必须执行此操作。
但是,如果您想进一步了解,这可能并不理想。更改维度时,此设置将在 arduino 发送端、arduino 读取端和 qml 端失败。您应该考虑发送数组的维度,读取这些维度并对其进行操作。一个想法可能是QAbstractListModel,它已经有了rows/columns的概念;另一个更简单的想法可能是向 Serial
class 添加属性,说明尺寸(在 readSerial()
中读取)