Ich brauche ein Modell zu erstellen, die ++ und QML-Code in C bearbeitet werden kann. Dieses Modell wird in einer Desktopanwendung verwendet, die sowohl Qt Widgets als auch Qml enthält. Für das qml Rendering verwende ich die QQuickWidget
.Probleme mit dem Bearbeiten von C++ QList <Object*> Modell in QML-Code und einige QML Warnungen
Ich habe Datenobjekt mit zwei Eigenschaften: Name und Farbe.
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();
}
}
für das Hauptfenster I Unterklasse von QMainWindow
verwenden. Das zentrale Widget enthält QQuickWidget
mit der Quelle MainView.qml. Im Konstruktor fülle ich das QList<Object*>
Modell und setze es als Kontexteigenschaft "nameColorModel" für 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 enthält einige zusätzliche Komponenten (firstTextField, secondComboBox, "OK" und "Abbrechen" -Tasten) und GroupBox
enthält Repeater
die benutzt mein "nameColorModel". NameColorEdit.qml wird als Stellvertreter von Repeater
verwendet.
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
}
}
}
Wenn ich Text in der "namefield" von NameColorEdit.qml ändern "nameColorModel" ändert sich nicht in С ++ Code . Wie kann ich das beheben?
Auch gibt es folgende Warnungen in QML-Code:
qrc:/MainView.qml:50:9: QML GroupBox: Binding loop detected for property "implicitWidth" qrc:/MainView.qml:61: ReferenceError: nameColorModel is not defined
Beachten Sie, dass das Modell nach dem Aufruf setSource von QQuickWidget
eingestellt werden. Wie kann ich diese Warnungen beheben?
Sie können mir auch Empfehlungen zum Schreiben von Code geben.
Vielen Dank!
Ihre Ansicht wird erstellt, bevor die context -Eigenschaft festgelegt wird, so dass der erste Lauf über nameColorModel beschwert wird. Versuchen Sie, die contextproperty früher festzulegen. – arynaq
Sie sollten auch eine "Data Handler" -Klasse in Betracht ziehen, die Ihre Wertepaare verwaltet und Signale für Änderungsbenachrichtigungen bereitstellt und diese in einem Tabellenmodell für QtWidgets und einem Listenmodell für QtQuick verwendet. Alternativ ein Tabellenmodell für beide Fälle, das aber die QML-Eigenschaften in Spalten abbildet –
@arynaq, Gibt es eine Möglichkeit, Kontexteigenschaften nach der Erstellung von Ansichten ohne Warnungen festzulegen? – user7655285