我是QML的新手。
我已经从免费的Web API中获取了一些JSON对象,现在我有了HackNewsModel
,这是QAbstractListModel
的自定义版本。
模型的头文件。
#ifndef HACKNEWSMODEL_H
#define HACKNEWSMODEL_H
#include "Singleton.hpp"
#include <QAbstractListModel>
#include <QJsonObject>
#include <QDateTime>
struct HackNews
{
QString m_id;
bool m_deleted;
QString m_type;
QString m_by;
QDateTime m_time;
QString m_text;
bool m_dead;
QString m_parentId;
QString m_pollId;
QStringList m_kidsIdList;
QString m_url;
QString m_score;
QString m_title;
QStringList m_partsIdList;
QString m_descendantCount;
};
class HackNewsModel : public QAbstractListModel, public Singleton<HackNewsModel>
{
Q_OBJECT
public:
void addHackNews(QJsonObject &hackNews);
enum Roles {
Id = Qt::UserRole + 1,
Deleted,
Type,
By,
Time,
Text,
Dead,
Parent,
Poll,
Kids,
URL,
Score,
Title,
Parts,
Descendents
};
QHash<int, QByteArray> roleNames() const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role/* = Qt::DisplayRole*/) const override;
friend class Singleton<HackNewsModel>;
explicit HackNewsModel(QObject * parent = nullptr);
~HackNewsModel() override;
private:
QList<HackNews> m_hackNewsList;
QHash<int, QByteArray> m_roles;
};
#endif // HACKNEWSMODEL_H
Cpp文件。
#include "HackNewsModel.h"
#include <QJsonArray>
#include <QDebug>
HackNewsModel::HackNewsModel(QObject *parent) : QAbstractListModel(parent)
{
m_roles[Id] = "id";
m_roles[Deleted] = "deleted";
m_roles[Type] = "type";
m_roles[By] = "by";
m_roles[Time] = "time";
m_roles[Text] = "text";
m_roles[Dead] = "dead";
m_roles[Parent] = "parent";
m_roles[Poll] = "poll";
m_roles[Kids] = "kids";
m_roles[URL] = "url";
m_roles[Score] = "score";
m_roles[Title] = "title";
m_roles[Parts] = "parts";
m_roles[Descendents] = "descendents";
}
HackNewsModel::~HackNewsModel()
{
}
void HackNewsModel::addHackNews(QJsonObject &hackNews)
{
QString id = "Demo id";
bool deleted = false;
QString type;
QString by;
QDateTime time;
QString text;
bool dead = false;
QString parentId;
QString pollId;
QStringList kidsIdList;
QString url;
QString score;
QString title;
QStringList partsIdList;
QString descendantCount;
if(hackNews.contains("id"))
{
id = hackNews["id"].toVariant().toString();
}
if(hackNews.contains("deleted"))
{
deleted = hackNews["deleted"].toBool();
}
if(hackNews.contains("type"))
{
type = hackNews["type"].toString();
}
if(hackNews.contains("by"))
{
by = hackNews["by"].toString();
}
if(hackNews.contains("time"))
{
time = QDateTime::fromTime_t(static_cast<unsigned int>(hackNews["time"].toInt()));
}
if(hackNews.contains("text"))
{
text = hackNews["text"].toString();
}
if(hackNews.contains("dead"))
{
dead = hackNews["dead"].toBool();
}
if(hackNews.contains("parent"))
{
parentId = hackNews["parent"].toVariant().toString();
}
if(hackNews.contains("poll"))
{
pollId = hackNews["poll"].toVariant().toString();
}
if(hackNews.contains("kids"))
{
foreach (QVariant value, hackNews["kids"].toArray().toVariantList()) {
kidsIdList.append(value.toString());
}
}
if(hackNews.contains("url"))
{
url = hackNews["url"].toString();
}
if(hackNews.contains("title"))
{
title = hackNews["title"].toString();
}
if(hackNews.contains("parts"))
{
foreach (QVariant value, hackNews["parts"].toArray().toVariantList()) {
partsIdList.append(value.toString());
}
}
if(hackNews.contains("descendents"))
{
descendantCount = hackNews["descendents"].toVariant().toString();
}
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_hackNewsList.append(HackNews{id, deleted, type, by, time, text, dead, parentId, pollId, kidsIdList, url, score, title, partsIdList, descendantCount});
endInsertRows();
}
QHash<int, QByteArray> HackNewsModel::roleNames() const
{
return m_roles;
}
int HackNewsModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_hackNewsList.size();
}
QVariant HackNewsModel::data(const QModelIndex &index, int role) const
{
QVariant result;
if(hasIndex(index.row(), index.column(), index.parent()))
{
const HackNews &news = m_hackNewsList.at(index.row());
switch (role) {
case Id:
{
result = news.m_id;
}
break;
case Deleted:
{
result = news.m_deleted;
}
break;
case Type:
{
result = news.m_type;
}
break;
case By:
{
result = news.m_by;
}
break;
case Time:
{
result = news.m_time;
}
break;
case Text:
{
result = news.m_text;
}
break;
case Dead:
{
result = news.m_dead;
}
break;
case Parent:
{
result = news.m_parentId;
}
break;
case Poll:
{
result = news.m_pollId;
}
break;
case Kids:
{
result = news.m_kidsIdList;
}
break;
case URL:
{
result = news.m_url;
}
break;
case Score:
{
result = news.m_score;
}
break;
case Title:
{
result = news.m_title;
}
break;
case Parts:
{
result = news.m_partsIdList;
}
break;
case Descendents:
{
result = news.m_descendantCount;
}
break;
default:
break;
}
}
return result;
}
我在以下代码中将模型暴露给QML。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "NetworkRequestMaker.h"
#include "HackNewsModel.h"
#include <QtWebEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
NetworkRequestMaker testRequestMaker;
qmlRegisterSingletonType<HackNewsModel>("HackNews", 1, 0, "HackNewsModel",
[](QQmlEngine *eng, QJSEngine *js) -> QObject *
{
eng->setObjectOwnership(&HackNewsModel::getInstance(),
QQmlEngine::ObjectOwnership::CppOwnership);
return &HackNewsModel::getInstance();
});
QtWebEngine::initialize();
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
使用ListView
可以吗?如何从QML访问HackNewsModel中的QStringList类型m_kidsIdList
?
最终,我想显示下图所示的JSON对象内容,即在浏览器中的外观。
我制作的模型是否有利于显示JSON对象,如图像中所示?您能建议我如何正确显示它吗?
谢谢。