qt — Проблемы с редактированием C ++ QList & lt; Object * & gt; модель в коде Qml и некоторые предупреждения Qml

Мне нужно создать модель, которую можно редактировать в коде C ++ и Qml. Эта модель будет использоваться в настольном приложении, которое содержит как Qt Widgets, так и Qml. Для рендеринга qml я использую QQuickWidget,

У меня есть объект данных с двумя свойствами: имя и цвет.

dataobject.h

#ifndef DATAOBJECT_H
#define DATAOBJECT_H

#include <QObject>

class DataObject : public QObject
{
Q_OBJECT

Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)

public:
DataObject(QObject *parent = Q_NULLPTR);
DataObject(const QString &name, const QString &color, QObject *parent = Q_NULLPTR);

QString name() const;
void setName(const QString &name);

QString color() const;
void setColor(const QString &color);

signals:
void nameChanged();
void colorChanged();

private:
QString m_name;
QString m_color;
};

#endif // DATAOBJECT_H

dataobject.cpp

#include "dataobject.h"
#include <QDebug>

DataObject::DataObject(QObject *parent)
: QObject(parent)
{
}

DataObject::DataObject(const QString &name, const QString &color, QObject *parent)
: QObject(parent), m_name(name), m_color(color)
{
}

QString DataObject::name() const
{
return m_name;
}

void DataObject::setName(const QString &name)
{
qDebug() << Q_FUNC_INFO;

if (name != m_name) {
m_name = name;
emit nameChanged();
}
}

QString DataObject::color() const
{
return m_color;
}

void DataObject::setColor(const QString &color)
{
qDebug() << Q_FUNC_INFO;

if (color != m_color) {
m_color = color;
emit colorChanged();
}
}

Для главного окна я использую подкласс QMainWindow, Центральный виджет содержит QQuickWidget с источником MainView.qml. В конструкторе я заполняю QList<Object*> модель и установите его как свойство контекста «nameColorModel» для MainView.qml.

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
Q_OBJECT

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

public slots:
void onAccepted();

private:
QList<QObject*> nameColorModel;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"#include "dataobject.h"
#include <QQuickWidget>
#include <QQmlContext>
#include <QQuickItem>

#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
auto qmlWidget = new QQuickWidget(QUrl("qrc:/MainView.qml"), this);
qmlWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);

this->setCentralWidget(qmlWidget);
this->resize(600, 400);

nameColorModel.append(new DataObject("Item 1", "red"));
nameColorModel.append(new DataObject("Item 2", "green"));
nameColorModel.append(new DataObject("Item 3", "blue"));
nameColorModel.append(new DataObject("Item 4", "yellow"));

qmlWidget->rootContext()->setContextProperty("nameColorModel", QVariant::fromValue(nameColorModel));

connect(qmlWidget->rootObject(), SIGNAL(accepted()), SLOT(onAccepted()));
}

MainWindow::~MainWindow()
{
qDeleteAll(nameColorModel.begin(), nameColorModel.end());
}

void MainWindow::onAccepted()
{
for(auto& object: nameColorModel)
{
auto item = qobject_cast<DataObject*>(object);
qDebug() << item->name() << item->color();
}
}

MainView.qml содержит некоторые дополнительные компоненты (firstTextField, secondComboBox, кнопки «ОК» и «Отмена») и GroupBox содержащий Repeater который использует мой «nameColorModel». NameColorEdit.qml используется в качестве делегата Repeater,

MainView.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1

import "." as Views

Item {
id: root
width: 600
height: 400

property alias firstText: firstTextField.text
property alias secondText: secondComboBox.currentText

signal accepted()
signal rejected()

ColumnLayout {
spacing: 10
anchors.fill: parent
anchors.margins: 10

GridLayout {
columns: 2
rowSpacing: 10
columnSpacing: 10

Label {
text: "First"}

TextField {
id: firstTextField
implicitHeight: 42
Layout.fillWidth: true
}

Label {
text: "Second"}

ComboBox {
id: secondComboBox
implicitHeight: 42
model: 5
Layout.fillWidth: true
}
}

GroupBox {
title: qsTr("Name-color objects:")
Layout.fillWidth: true

ColumnLayout {
id: col
spacing: 10
anchors.fill: parent

Repeater {
id: repeater
model: nameColorModel ////  <-- QList<Object*> model

Views.NameColorEdit {
name: modelData.name
color: modelData.color
Layout.row: index
Layout.fillWidth: true
}
}
}
}

Item {
Layout.fillHeight: true
}

RowLayout {
Layout.alignment: Qt.AlignRight

Button {
text: "Ок"Layout.minimumWidth: 42
Layout.minimumHeight: 42
onClicked: accepted()
}

Button {
text: "Cancel"Layout.minimumWidth: 42
Layout.minimumHeight: 42
onClicked: rejected()
}
}
}
}

NameColorEdit.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1

Item {
id: root
implicitWidth: nameField.implicitWidth
implicitHeight: nameField.implicitHeight

property alias name: nameField.text
property alias color: colorField.text

RowLayout {
spacing: 10
anchors.fill: parent

Label {
text: "Color"}

TextField {
id: colorField
enabled: false
implicitWidth: 150
implicitHeight: 42
}

Label {
text: "Name"}

TextField {
id: nameField
implicitHeight: 42
Layout.fillWidth: true
}
}
}

Когда я изменяю текст в «nameField» NameColorEdit.qml, «nameColorModel» не изменяется в коде С ++.
Как я могу это исправить?

Также есть следующие предупреждения в qml-коде:

qrc: /MainView.qml: 50: 9: QML GroupBox: обнаружен цикл привязки для
свойство «implicitWidth» qrc: /MainView.qml: 61: ReferenceError:
nameColorModel не определено

Обратите внимание, что модель будет установлена ​​после вызова setSource QQuickWidget,
Как я могу исправить эти предупреждения?

Вы также можете дать мне рекомендации по написанию кода.

Спасибо!

1

Решение

Проблема была решена с помощью Binding за DataObject собственность и NameColorEdit имущество:

        Repeater {
id: repeater
model: nameColorModel ////  <-- QList<Object*> model

Views.NameColorEdit {
name: modelData.name
color: modelData.color
Layout.row: index
Layout.fillWidth: true

Binding { target: modelData; property: "name"; value: name }
Binding { target: modelData; property: "color"; value: color }
}
}

Теперь при редактировании nameField в NameColorEdit.qml содержимое QList<Object*> Модель в коде C ++ успешно обновлена. Кроме того, если мы изменим содержание QList<Object*> модель в коде C ++, NameColorEdit.qml будет обновлен.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]