Я хочу показать ListView с моделью, то есть QVector пользовательского класса. Этот вопрос почти такой же Qt QML C++ QList структур, что и пользовательская модель ListView, но решение у меня не работает. Вот класс, содержащий поля. Сигналы и запись-чтение генерируются автоматически.
class Subject : public QObject
{
Q_OBJECT
public:
int First;
int Second;
explicit Subject(int fFirst = 0, int fSecond = 0, QObject *parent = nullptr)
{
this->First = fFirst;
this->Second = fSecond;
emit FirstChanged();
emit SecondChanged();
}
Subject::Subject(const Subject &Copy)
{
this->First = Copy.First;
this->Second = Copy.Second;
emit FirstChanged();
emit SecondChanged();
}
void Subject::operator=(const Subject &Right)
{
this->First = Right.First;
this->Second = Right.Second;
}
private:
Q_PROPERTY(int _First READ getFirst WRITE setFirst NOTIFY FirstChanged FINAL)
Q_PROPERTY(int _Second READ getSecond WRITE setSecond NOTIFY SecondChanged FINAL)
};
Вот класс контроллера
class Controller : public QObject
{
Q_OBJECT
public:
explicit Controller(QObject *parent = nullptr)
{
this->List.push_back(Subject(1, 0));
this->List.push_back(Subject(2, 0));
}
QVector<Subject> List;
QVector<Subject> getList() const;
void setList(const QVector<Subject> &newList);
Q_INVOKABLE void printAll();
private:
Q_PROPERTY(QVector<Subject> _List READ getList CONSTANT)
};
Qml main - это окно с этим
Controller
{
id: _Controller
Component.onCompleted:
{
_Controller.printAll()
}
}
ListView
{
anchors.fill: parent
model: _Controller._List
Component.onCompleted:
{
for (let i = 0; i < 2; i++)
{
console.info(_Controller._List[0])
}
}
delegate: Text {
id: _delegated
text: qsTr(modelData._First)
font.bold: true
color: "black"
font.pointSize: 24
}
}
Я в значительной степени последовал решению, но на экране ничего не появилось. «Список» не пуст по завершению. Пытался изменить его, чтобы он не был константным, и выдавать ListChanged после запуска приложения, но текст не появляется. Когда я пытаюсь выполнить перебор вектора в ListView, вот так
Component.onCompleted:
{
for (let i = 0; i < 2; i++)
{
console.info(_Controller._List)
}
}
я понимаю это
qml: QVariant(QList<Subject>, )
qml: QVariant(QList<Subject>, )
Вы также зарегистрировали класс «Предмет»? Более того, почему бы просто не использовать QAbstractListModel?
@morteza Да, я зарегистрировал это. Спасибо за совет по поводу QAbstractListModel, не знал о нем. Но если бы я это сделал - я бы, наверное, не хотел усложнять приложение другим классом, если бы мог добиться того же результата и без него.
Я вижу здесь целый букет различных нарушений. излучать сигнал от конструктора? В этом случае объект все еще не существует. частная собственность? какой в этом смысл?
@folibis Я знаю, что генерирование в конструкторе мало что дает, IDE говорит то же самое, но я был в отчаянии, поэтому пробовал что угодно. А частная собственность - чтобы их генерировала IDE и она прекрасно работает.





В вашем коде есть несколько ошибок. Но благодаря следующему изменению, предложенному Доступ к спискам QLists C++ из QML, проблема будет решена (проверено).
#include "subject.h"
class Controller : public QObject
{
Q_OBJECT
Q_PROPERTY(QVector<Subject*> _List READ getList CONSTANT)
public:
explicit Controller(QObject *parent = nullptr){
this->List.push_back(new Subject(1, 0));
this->List.push_back(new Subject(2, 0));
}
QVector<Subject*> List;
QVector<Subject*> getList() const{
return this->List;
}
};
Главный вывод меняется
QVector<Subject> _List
к
QVector<Subject*> _List
и некоторые другие последующие изменения. Более того, классы «Субъект» и «Контроллер» должны быть зарегистрированы перед загрузкой механизма QML. Что-то вроде этого:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<Controller>("Controller",1,0,"Controller");
qmlRegisterUncreatableType<Subject>("Subject",1,0,"Subject","Reference only");
QQmlApplicationEngine engine;
QObject::connect(&engine,engine.objectCreationFailed,&app,[&app](){app.exit(-1);});
engine.loadFromModule("Main","Main");
return app.exec();
}
Спасибо за ответ, да, кажется, это решает проблему, но также необходимо преобразовать значение modelData._First в строку, поэтому property int value: modelData.first требуется перед использованием его в тексте.
@VoiceShifter Конечно. Если вы настаиваете на использовании qsTr.
Я старался сделать вопрос максимально компактным, но текст все равно гигантский.