来自 C++ 的 QStandardItemModel 在 QtQuick/QML TableView 中不可见
QStandardItemModel from C++ not visisble in QtQuick / QML TableView
我已经对 QStandardItemModel 进行了子class编辑,并希望 link 它与 QML 中的 TableView 一起使用。但是来自 QStandardItemModel 的数据在 TableView 中是不可见的。
在表视图中将角色设置为 "display" 我能够看到第一列,因此我在我的 class 中重新实现了 roleNames() 函数,但仍然没有成功。
我不确定如何 link roleNames enum with column in QStandardItemModel?
class AuditLogsModel : public QStandardItemModel
{
Q_OBJECT
QList<QStandardItem*> row;
public:
enum AuditRoles
{
DateTimeRole = Qt::UserRole + 1,
UsernameRole,
ApplicationRole,
CategoryRole,
DescriptionRole
};
...
Implementation (C++) source
AuditLogsModel::AuditLogsModel(QObject *parent)
: QStandardItemModel(parent)
{
row.clear();
loadData();
setColumnMapping();
}
void AuditLogsModel::setColumnMapping()
{
setData(index(0,0), "DateTime", AuditRoles::DateTimeRole);
setData(index(0,1), "Name", AuditRoles::UsernameRole);
setData(index(0,2), "Application", AuditRoles::ApplicationRole);
setData(index(0,3), "Category", AuditRoles::CategoryRole);
setData(index(0,4), "Description", AuditRoles::DescriptionRole);
}
QHash<int, QByteArray> AuditLogsModel::roleNames() const
{
QHash<int, QByteArray> roleNameMap;
roleNameMap[DateTimeRole] = "DateTime";
roleNameMap[UsernameRole] = "Name";
roleNameMap[ApplicationRole] = "Application";
roleNameMap[CategoryRole] = "Category";
roleNameMap[DescriptionRole] = "Description";
return roleNameMap;
}
void AuditLogsModel::loadData()
{
QFile file(AUDIT_LOG_PATH);
if( file.exists() == false )
{
syslog(LOG_ERR,qPrintable(QString("Audit log file: %1 does not exist").arg(AUDIT_LOG_PATH)));
return;
}
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
QJsonObject logEntry;
while(!in.atEnd()) {
line = in.readLine();
logEntry = (QJsonDocument::fromJson(line.toStdString().c_str())).object();
row.append(new QStandardItem(logEntry["Date-time"].toString()));
row.append(new QStandardItem(logEntry["username"].toString()));
row.append(new QStandardItem(logEntry["App_name"].toString()));
row.append(new QStandardItem(logEntry["event_category"].toString()));
row.append(new QStandardItem(logEntry["event_desc"].toString()));
appendRow(row);
row.clear();
}
file.close();
}
}
QML代码
TableView {
id: auditLogTable
[geometry]
model: auditLogModelObj
TableViewColumn {
role: "DateTime"
title: qsTr("Local Time")
width: auditLogTable.width * 0.15
}
TableViewColumn {
role: "Name"
title: qsTr("Created By")
width: auditLogTable.width * 0.1
}
TableViewColumn {
role: "Application"
title: qsTr("app name")
width: auditLogTable.width * 0.40
}
TableViewColumn {
role: "Category"
title: qsTr("Category")
width: auditLogTable.width * 0.2
}
TableViewColumn {
role: "Description"
title: qsTr("Detail")
width: auditLogTable.width * 0.40
}
}
我不明白你试图在 setColumnMapping() 中做什么,你也不需要使用 roleNames()。另外,您使用的TableView只接受列表类型的模型,在这种情况下角色将是列,考虑到解决方案是:
*.h
class AuditLogsModel : public QStandardItemModel
{
public:
enum AuditRoles{
DateTimeRole = Qt::UserRole + 1,
UsernameRole,
ApplicationRole,
CategoryRole,
DescriptionRole
};
AuditLogsModel(QObject *parent=nullptr);
void loadData();
};
*.cpp
AuditLogsModel::AuditLogsModel(QObject *parent):
QStandardItemModel(parent)
{
QHash<int, QByteArray> roles;
roles[DateTimeRole] = "DateTime";
roles[UsernameRole] = "Name";
roles[ApplicationRole] = "Application";
roles[CategoryRole] = "Category";
roles[DescriptionRole] = "Description";
setItemRoleNames(roles);
}
void AuditLogsModel::loadData()
{
QFile file(AUDIT_LOG_PATH);
if(!file.exists() )
{
syslog(LOG_ERR,qPrintable(QString("Audit log file: %1 does not exist").arg(AUDIT_LOG_PATH)));
return;
}
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
QJsonObject logEntry;
while(!in.atEnd()) {
QStandardItem *row = new QStandardItem;
line = in.readLine();
logEntry = (QJsonDocument::fromJson (line.toStdString().c_str())).object();
row->setData(logEntry["Date-time"].toString(), DateTimeRole);
row->setData(logEntry["username"].toString(), UsernameRole);
row->setData(logEntry["App_name"].toString(), ApplicationRole);
row->setData(logEntry["event_category"].toString(), CategoryRole);
row->setData(logEntry["event_desc"].toString(), DescriptionRole);
appendRow(row);
}
file.close();
}
}
我已经对 QStandardItemModel 进行了子class编辑,并希望 link 它与 QML 中的 TableView 一起使用。但是来自 QStandardItemModel 的数据在 TableView 中是不可见的。
在表视图中将角色设置为 "display" 我能够看到第一列,因此我在我的 class 中重新实现了 roleNames() 函数,但仍然没有成功。 我不确定如何 link roleNames enum with column in QStandardItemModel?
class AuditLogsModel : public QStandardItemModel
{
Q_OBJECT
QList<QStandardItem*> row;
public:
enum AuditRoles
{
DateTimeRole = Qt::UserRole + 1,
UsernameRole,
ApplicationRole,
CategoryRole,
DescriptionRole
};
...
Implementation (C++) source
AuditLogsModel::AuditLogsModel(QObject *parent)
: QStandardItemModel(parent)
{
row.clear();
loadData();
setColumnMapping();
}
void AuditLogsModel::setColumnMapping()
{
setData(index(0,0), "DateTime", AuditRoles::DateTimeRole);
setData(index(0,1), "Name", AuditRoles::UsernameRole);
setData(index(0,2), "Application", AuditRoles::ApplicationRole);
setData(index(0,3), "Category", AuditRoles::CategoryRole);
setData(index(0,4), "Description", AuditRoles::DescriptionRole);
}
QHash<int, QByteArray> AuditLogsModel::roleNames() const
{
QHash<int, QByteArray> roleNameMap;
roleNameMap[DateTimeRole] = "DateTime";
roleNameMap[UsernameRole] = "Name";
roleNameMap[ApplicationRole] = "Application";
roleNameMap[CategoryRole] = "Category";
roleNameMap[DescriptionRole] = "Description";
return roleNameMap;
}
void AuditLogsModel::loadData()
{
QFile file(AUDIT_LOG_PATH);
if( file.exists() == false )
{
syslog(LOG_ERR,qPrintable(QString("Audit log file: %1 does not exist").arg(AUDIT_LOG_PATH)));
return;
}
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
QJsonObject logEntry;
while(!in.atEnd()) {
line = in.readLine();
logEntry = (QJsonDocument::fromJson(line.toStdString().c_str())).object();
row.append(new QStandardItem(logEntry["Date-time"].toString()));
row.append(new QStandardItem(logEntry["username"].toString()));
row.append(new QStandardItem(logEntry["App_name"].toString()));
row.append(new QStandardItem(logEntry["event_category"].toString()));
row.append(new QStandardItem(logEntry["event_desc"].toString()));
appendRow(row);
row.clear();
}
file.close();
}
}
QML代码
TableView {
id: auditLogTable
[geometry]
model: auditLogModelObj
TableViewColumn {
role: "DateTime"
title: qsTr("Local Time")
width: auditLogTable.width * 0.15
}
TableViewColumn {
role: "Name"
title: qsTr("Created By")
width: auditLogTable.width * 0.1
}
TableViewColumn {
role: "Application"
title: qsTr("app name")
width: auditLogTable.width * 0.40
}
TableViewColumn {
role: "Category"
title: qsTr("Category")
width: auditLogTable.width * 0.2
}
TableViewColumn {
role: "Description"
title: qsTr("Detail")
width: auditLogTable.width * 0.40
}
}
我不明白你试图在 setColumnMapping() 中做什么,你也不需要使用 roleNames()。另外,您使用的TableView只接受列表类型的模型,在这种情况下角色将是列,考虑到解决方案是:
*.h
class AuditLogsModel : public QStandardItemModel
{
public:
enum AuditRoles{
DateTimeRole = Qt::UserRole + 1,
UsernameRole,
ApplicationRole,
CategoryRole,
DescriptionRole
};
AuditLogsModel(QObject *parent=nullptr);
void loadData();
};
*.cpp
AuditLogsModel::AuditLogsModel(QObject *parent):
QStandardItemModel(parent)
{
QHash<int, QByteArray> roles;
roles[DateTimeRole] = "DateTime";
roles[UsernameRole] = "Name";
roles[ApplicationRole] = "Application";
roles[CategoryRole] = "Category";
roles[DescriptionRole] = "Description";
setItemRoleNames(roles);
}
void AuditLogsModel::loadData()
{
QFile file(AUDIT_LOG_PATH);
if(!file.exists() )
{
syslog(LOG_ERR,qPrintable(QString("Audit log file: %1 does not exist").arg(AUDIT_LOG_PATH)));
return;
}
if (file.open(QIODevice::ReadOnly))
{
QTextStream in(&file);
QString line;
QJsonObject logEntry;
while(!in.atEnd()) {
QStandardItem *row = new QStandardItem;
line = in.readLine();
logEntry = (QJsonDocument::fromJson (line.toStdString().c_str())).object();
row->setData(logEntry["Date-time"].toString(), DateTimeRole);
row->setData(logEntry["username"].toString(), UsernameRole);
row->setData(logEntry["App_name"].toString(), ApplicationRole);
row->setData(logEntry["event_category"].toString(), CategoryRole);
row->setData(logEntry["event_desc"].toString(), DescriptionRole);
appendRow(row);
}
file.close();
}
}