来自 C++ 的 QStandardItemModel 在 QtQuick / QML TableView 中不可见

Posted

技术标签:

【中文标题】来自 C++ 的 QStandardItemModel 在 QtQuick / QML TableView 中不可见【英文标题】:QStandardItemModel from C++ not visisble in QtQuick / QML TableView 【发布时间】:2019-03-26 22:43:49 【问题描述】:

我已将 QStandardItemModel 子类化,并希望将其与 QML 中的 TableView 链接。但是来自 QStandardItemModel 的数据在 TableView 中不可见。

在 tableview 中将角色设置为“显示”后,我可以看到第一列,因此我在课堂上重新实现了 roleNames() 函数,但仍然没有成功。 我不确定如何将 roleNames 枚举与 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
        
    

【问题讨论】:

您的AuditLogsModel::setData() 方法在哪里?看看这个:***.com/questions/17050573/… 【参考方案1】:

我不明白你在 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();
    

【讨论】:

以上是关于来自 C++ 的 QStandardItemModel 在 QtQuick / QML TableView 中不可见的主要内容,如果未能解决你的问题,请参考以下文章

来自 Python | 的远程过程调用红宝石 | ... 到 C++

JNI - 来自 C++ 的免费 ByteBuffer

C++ 重载 == 比较来自不同类的对象

来自 C++ 的回调 python 函数,对象被破坏

解释来自 Superpowered CrossExample for Android 的 C++ 代码

求职作业帮 C++方向面经