已解决:我做了所有类似eyllanesc的回答,并且在我的FirstPage.qml中 委托我访问模型数据的位置,我将modelData放在名称之前。 以前我在FirstPage.qml委托中使用过:名称,已完成和 未完成,现在我使用modelData.name,modelData.completed和 modelData.uncomplete。现在一切都很好。
我是QT / QML的新手,我尝试过但找不到解决问题的答案。
我在QML中使用模型(在c ++中创建)。当应用程序启动时,一切都很好,但是当我尝试添加新元素进行建模时,它不会显示在QML中。模型从一开始就是一样。
我有类modcontroller,并且在其中创建列表。
modcontroller.h
#ifndef MODCONTROLLER_H
#define MODCONTROLLER_H
#include <QObject>
#include <list.h>
class modcontroller : public QObject
{
Q_OBJECT
public:
explicit modcontroller(QObject *parent = nullptr);
QList<QObject*> getList();
Q_INVOKABLE void addList(QString nam);
signals:
void listChanged();
public slots:
private:
QList<QObject*> m_dataList;
};
#endif // MODCONTROLLER_H
modcontroller.cpp
#include "modcontroller.h"
#include <QDebug>
modcontroller::modcontroller(QObject *parent) : QObject(parent)
{
m_dataList.append(new List("Test"));
}
QList<QObject *> modcontroller::getList()
{
return m_dataList;
}
void modcontroller::addList(QString nam)
{
m_dataList.append(new List(nam));
qDebug() << "Function addList called";
qDebug() << m_dataList;
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "list.h"
#include "modcontroller.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
modcontroller controller;
engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(controller.getList()));
engine.rootContext()->setContextProperty("controller",&controller);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
在QML文件中,我具有带有model: myModel
的ListView和带有
onClicked: {
controller.addList(textInput.text)
myStackView.push(firstPage)
}
当我单击“创建”时,我仅看到开始时创建的第一项“测试”,但在控制台中却看到了:
Function addList called
(List(0x2b7e60bc2c0), List(0x2b82d5891b0))
谢谢。
main.qml
ApplicationWindow {
visible: true
width: 580
height: 360
title: qsTr("Hello World")
StackView{
id: myStackView
initialItem: firstPage
anchors.fill: parent
}
Component{
id: firstPage
FirstPage{}
}
Component{
id: createNewListPage
CreateNewListPage{}
}
}
FirstPage.qml
Item {
ListView{
id: lists
width: 150
height: childrenRect.height
x: 15
y: 70
model: myModel
delegate: Row{
width: 150
height: 25
spacing: 5
Rectangle{
width: {
if(uncompleted < 3){return 3;}
else if(uncompleted < 6){return 6;}
else {return 10;}
}
height: {
if(uncompleted < 3){return 3;}
else if(uncompleted < 6){return 6;}
else {return 10;}
}
radius: 10
color: "#494949"
anchors.verticalCenter: parent.verticalCenter
}
Button {
id:button1
height: 23
contentItem: Text {
id: textTask
text: name
font.underline: true
color: "blue"
font.bold: true
font.pointSize: 10
height: 20
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
}
background: Rectangle {
id: rectangle
color: "transparent"
}
states:[
State {
name: "Hovering"
PropertyChanges {
target: textTask
color: "white"
font.bold: true
font.underline: false
}
PropertyChanges {
target: rectangle
color: "blue"
}
}]
MouseArea{
hoverEnabled: true
anchors.fill: button1
onEntered: { button1.state='Hovering'}
onExited: { button1.state=''}
}
}
Text{
font.pointSize: 8
text: {
if(uncompleted == 0)return "";
return "- " + uncompleted + " left";
}
color: "#494949"
anchors.verticalCenter: parent.verticalCenter
}
}
}
}
CreateNewListPage.qml
Item {
Rectangle{
width: 580
height: 360
Rectangle{
width: 350
height: 30
y: 100
x: 30
border.color: "#7b9cd3"
border.width: 1
TextInput {
id: textInput
anchors.topMargin: 3
cursorVisible: true
anchors.fill: parent
font.bold: true
font.pointSize: 14
}
}
Button{
height: 20
text: "Create this list"
onClicked: {
controller.addList(textInput.text)
myStackView.push(firstPage)
}
background: Rectangle{
id: rect1
anchors.fill: parent
radius: 20
border.color: "#88b6cf"
gradient: Gradient {
GradientStop { position: 0.0; color: "#fcfefe" }
GradientStop { position: 1.0; color: "#d5e8f3" }
}
}
}
}
}
答案 0 :(得分:0)
列表是一个虚拟模型,因为它本身不会通知视图是否发生任何更改(例如元素数量),因此针对您的情况的解决方案是使其成为mod_controller的Q_PROPERTY,然后在添加项目时,标志listChanged将通知视图某些内容已更改,因此需要重新粉刷。由于Q_PROPERTY可在QML中访问,因此不必与控制器分开导出列表,因此解决方案是:
modcontroller.h
#ifndef MODCONTROLLER_H
#define MODCONTROLLER_H
#include <QObject>
class modcontroller : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QObject *> lists READ getList NOTIFY listsChanged) // <---
public:
explicit modcontroller(QObject *parent = nullptr);
QList<QObject *> getList() const;
Q_INVOKABLE void addList(const QString &nam);
Q_SIGNAL void listsChanged();
private:
QList<QObject*> m_dataList;
};
#endif // MODCONTROLLER_H
modcontroller.cpp
#include "modcontroller.h"
#include "list.h"
#include <QDebug>
modcontroller::modcontroller(QObject *parent) : QObject(parent)
{
m_dataList.append(new List("Test"));
}
QList<QObject *> modcontroller::getList() const
{
return m_dataList;
}
void modcontroller::addList(const QString & nam)
{
m_dataList.append(new List(nam));
qDebug() << "Function addList called";
qDebug() << m_dataList;
Q_EMIT listsChanged(); // <---
}
main.cpp
#include "modcontroller.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
modcontroller controller;
engine.rootContext()->setContextProperty("controller",&controller);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
对于QML,绑定是通过控制器的Q_PROPERTY列表完成的:
ListView{
// ...
model: controller.lists // <---
// ...