從json數組構造QAbstractTableModel子類,快速繪製QTableView

一般的,QSqlTableModel可以關聯數據庫的一張表,QTableView對象通過setModel,關聯這個model對象,這樣,編碼上很方便能將QTableView展示成數據庫表的樣式。

但是如果數據來源不是數據庫表,而是json數組,則需要繼承QAbstractTableModel,然後再讓tableview->setModel。

下文的AbsTblMdlJsonArray就簡易地實現了這個功能。

#pragma once
#include <memory>
#include <QAbstractTableModel>
#include <QJsonArray>

class AbsTblMdlJsonArray : public QAbstractTableModel {
public:
	AbsTblMdlJsonArray(const QJsonArray &src, QObject *parent = Q_NULLPTR);
	int	columnCount(const QModelIndex &parent = QModelIndex()) const override;
	QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
	//QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
	//QModelIndex parent(const QModelIndex &index) const override;
	int	rowCount(const QModelIndex &parent = QModelIndex()) const override;
	QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
protected:
	QJsonArray m_src;
	int m_rowCount;
	int m_columnCount = 0;
	QVariantMap m_vmapHead;
	std::unique_ptr<QString[]> m_headers;
	QList<QVariantMap> m_data;
	QString currencyAt(int offset) const;
};
#include <QJsonObject>
#include "AbsTblMdlJsonArray.h"

AbsTblMdlJsonArray::AbsTblMdlJsonArray(const QJsonArray &src, QObject *parent)
	: QAbstractTableModel(parent)
	, m_src(src)
	, m_rowCount(src.count())
{
	if (m_rowCount > 0) {
		for (auto it = m_src.constBegin(); it != m_src.constEnd(); ++it) {
			if (it->isObject()) {
				m_data.push_back(it->toObject().toVariantMap());
			}
		}
		m_vmapHead = m_data.front();
		m_columnCount = m_vmapHead.count();
		m_headers = std::make_unique<QString[]>(m_columnCount);
		auto keys = m_vmapHead.keys();
		int i = 0;
		for (const auto &each : keys) {
			m_headers[i++] = each;
		}
	}	
}

int	AbsTblMdlJsonArray::columnCount(const QModelIndex &parent) const {
	return m_columnCount;
}

QString AbsTblMdlJsonArray::currencyAt(int offset) const {
	return (m_vmapHead.begin() + offset).key();
}

QVariant AbsTblMdlJsonArray::data(const QModelIndex &index, int role) const {
	if (!index.isValid())
		return QVariant();

	if (role == Qt::TextAlignmentRole) {
		return int(Qt::AlignRight | Qt::AlignVCenter);
	}
	else if (role == Qt::DisplayRole) {
		const auto row = m_data.at(index.row());
		return row.find(m_headers[index.column()]).value();
	}
	return QVariant();
}

int	AbsTblMdlJsonArray::rowCount(const QModelIndex &parent) const {
	return m_rowCount;
}

QVariant AbsTblMdlJsonArray::headerData(int section, Qt::Orientation orientation, int role) const {
	if (role == Qt::DisplayRole)
	{
		if (orientation == Qt::Horizontal) // ˮƽҭͷ  
		{
			return m_headers[section];
		}
	}

	return QVariant();
}

使用範例如下:

ui.setupUi(this);
	QString str("[	{\"a\":1,\"b\":0.1,\"c\":\"xx\"},\
					{\"a\":2,\"b\":0.2,\"c\":\"yy\"},\
					{\"a\":2,\"b\":0.2,\"c\":\"zz\"}]");
	QJsonParseError err;
	QJsonDocument jd = QJsonDocument::fromJson(str.toUtf8(), &err);
	QJsonArray ja = jd.array();
	m_data = std::make_unique<AbsTblMdlJsonArray>(ja, this);
	ui.tableView->setModel(m_data.get());

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章