gpt4 book ai didi

c++ - Qt:将 C++ 中的列表连接到 QML 中的 ListView

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:09:13 27 4
gpt4 key购买 nike

我刚开始学习 Qt。老实说,有些让我很困惑。我正在尝试将预定义的 .csv 表加载到 ListView 中。我创建了一个 qml 文件,其中包含一个文本字段、一个 ListView 和一个用于加载文件的按钮的简单布局。该文件如下所示:

import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2

ApplicationWindow {
id: applicationWindow
objectName: "App"
visible: true
width: 640
height: 480
title: qsTr("Rosinenpicker")

ColumnLayout {
id: columnLayout
anchors.rightMargin: 40
anchors.leftMargin: 40
anchors.bottomMargin: 40
anchors.topMargin: 40
anchors.fill: parent


TextField {
id: name
text: qsTr("Text Field")
Layout.preferredHeight: 50
Layout.fillWidth: true
}

ListView {
id: list
x: 0
y: 0
width: 110
height: 160
spacing: 0
boundsBehavior: Flickable.DragAndOvershootBounds
Layout.fillHeight: true
Layout.fillWidth: true
objectName: "listView"
model: guestModel

delegate: Item {
x: 5
width: 80
height: 40

Text {
text: model.modeldata.name
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
}
}

Button {
id: button
width: 50
text: qsTr("Open File")
Layout.preferredWidth: 100
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter

onClicked: fileDialog.visible = true;
}

FileDialog {
id: fileDialog
title: "Please choose a valid guestlist file"
objectName: "fileDialog"
nameFilters: ["Valid guestlist files (*.csv)"]
selectMultiple: false

signal fileSelected(url path)

onAccepted: fileSelected(fileDialog.fileUrl)
}
}
}

在我的主文件中,我创建了一个 CsvParser 类并将其连接到文件对话框的 fileSelected 信号。我可以解析 csv 文件。但是当我尝试将它连接到 ListView 时,我迷路了。

主文件:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtDebug>
#include <QUrl>
#include <QQuickView>

#include "csvparser.h"

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;

auto root = engine.rootObjects().first();
auto fileDialog = root->findChild<QObject*>("fileDialog");

CsvParser parser(engine.rootContext());
QObject::connect(fileDialog, SIGNAL(fileSelected(QUrl)), &parser, SLOT(loadData(QUrl)));

return app.exec();
}

我的解析器看起来像这样:

#include "csvparser.h"

#include <QtDebug>
#include <QFile>

#include "guest.h"

CsvParser::CsvParser(QQmlContext *context)
{
this->context = context;
}

void CsvParser::loadData(QUrl path)
{
friendList.clear();
guestList.clear();

QFile file(path.toLocalFile());
file.open(QIODevice::ReadOnly);

// ignore first lines
for(int i=0; i<3; i++)
file.readLine();

while(!file.atEnd()) {
auto rowCells = file.readLine().split(',');

if(rowCells.size() != 6)
continue;

checkedAdd(friendList, rowCells[0], rowCells[1]);
checkedAdd(guestList, rowCells[3], rowCells[4]);
}

qDebug() << guestList.size();
auto qv = QVariant::fromValue(guestList);
context->setContextProperty("guestModel", qv);
}

void CsvParser::checkedAdd(QList<QObject*> &list, QString name, QString familyName)
{
if(name == "" && familyName == "")
return;

list.append(new Guest(name, familyName));
}

而只有名字和姓氏的客人看起来像这样:

#ifndef GUEST_H
#define GUEST_H

#include <QObject>

class Guest : public QObject
{
public:
Q_OBJECT

Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString fName READ fName WRITE setfName NOTIFY fNameChanged)

public:
Guest(QString name, QString fName);

QString name();
QString fName();

void setName(QString name);
void setfName(QString fName);

signals:
void nameChanged();
void fNameChanged();

private:
QString m_name, m_fName;
};

#endif // GUEST_H

我得到以下输出:

qrc:/main.qml:41: ReferenceError: guestModel is not defined
QFileInfo::absolutePath: Constructed with empty filename
2
qrc:/main.qml:49: TypeError: Cannot read property 'name' of undefined
qrc:/main.qml:49: TypeError: Cannot read property 'name' of undefined

我做错了什么?任何帮助表示赞赏。谢谢!

最佳答案

有几点我认为是错误的。 QML 不会找到 guestModel,因为它会尝试呈现 ListView,但由于您在 loadData() 中设置上下文属性,QML 无法使用它,但是它仅在用户与 FileDialog 交互时调用。此外,Q_OBJECT 宏需要出现在类的私有(private)部分(参见 http://doc.qt.io/qt-5/qobject.html#Q_OBJECT)。另外,我认为让数据容器/解析器类了解 UI 并不是一件好事,即将 rootContext 导出到解析器。如果您将某些内容从解析器导出到 main 中的 rootContext 会更好。解析器应该没有 UI 恕我直言的概念。最后,如果您想实现要显示的数据项的自定义列表,您真的应该考虑使用 Yuki 建议的 AbstractListModel(参见 http://doc.qt.io/qt-5/qabstractlistmodel.html)或其他合适的基于列表的模型(参见 http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html) .这样,C++ 中的更改将自动导致 UI 中的更新。

关于c++ - Qt:将 C++ 中的列表连接到 QML 中的 ListView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44522577/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com