【问题标题】:qml TableView itemdelegate not firing (using a QAbstractTableModel)qml TableView itemdelegate 未触发(使用 QAbstractTableModel)
【发布时间】:2020-08-07 09:41:45
【问题描述】:

我试图让我的第一个 QML TableView 在 Qt 5.2 中工作(因为我们坚持 现在工作的版本)在后端使用QAbstractTableModel

我的主要问题是,由于某种原因,itemDelegate 永远不会触发,所以 除了TableView 的轮廓外,我从未在视图中看到任何东西。 我还验证了theData_ 填充了二维数字 在构造函数的每一行/列中,我执行emit layoutChanged() 以及构造函数中的emit dataChanged()

我意识到我在data() 调用中没有错误检查无效的QModelIndex 此时。

我也根本没有实现index()

还有没有必要在这里使用ROLE

我显示的数据是每个单元格的单个整数(QString),目前仅此而已。

感谢您的帮助

qml:

TableView {
  width: 600
  height: 600

  model: myModel
  visible: true

  itemDelegate: Rectangle {
     color: "lightgray"
     width: 100
     height: 20

     Text {
        text: styleData.value
        color: "black"
     }
   }
}

来自子类 QAbstractTableModel 的相关代码:

int MyModel::rowCount(const QModelIndex&) const
{
return 10;
}

int MyModel::columnCount(const QModelIndex&) const
{
return 3;
}

QVariant MyModel::data(const QModelIndex& index, int role) const
{
const int row = index.row();
const int col = index.column();

return QString("%1").arg(this->theData_[col][row]);
}

【问题讨论】:

    标签: qt qml tableview qitemdelegate


    【解决方案1】:

    在 Qt 5.12 之前,只有一个属于 Qt QuickControl 1 的 TableView 组件,它只支持列表类型模型,其中每一列都反映了角色的信息,所以这可能是您的问题,因为您还没有创建任何 TableViewColumn。另一方面,从 >= Qt5.12 开始,另一个 TableView 已经存在,它支持作为表类型模型。

    mymodel.h

    #ifndef MYMODEL_H
    #define MYMODEL_H
    
    #include <QAbstractListModel>
    
    struct Data{
        int number;
        QString text;
    };
    
    class MyModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum CustomRoles{
            NumberRole = Qt::UserRole,
            TextRole
        };
        explicit MyModel(QObject *parent = nullptr);
        int rowCount(const QModelIndex &parent = QModelIndex()) const override;
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
        QHash<int, QByteArray> roleNames() const override;
    private:
        QList<Data> m_data;
    };
    
    #endif // MYMODEL_H
    

    mymodel.cpp

    #include "mymodel.h"
    
    MyModel::MyModel(QObject *parent)
        : QAbstractListModel(parent)
    {
        // for test
        for(int i=0; i< 10; i++){
            Data d{i, QString::number(i)};
            m_data.push_back(d);
        }
    }
    
    int MyModel::rowCount(const QModelIndex &parent) const
    {
        if (parent.isValid())
            return 0;
        return m_data.count();
    }
    
    QVariant MyModel::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
        if(role == NumberRole)
            return m_data.at(index.row()).number;
        if(role == TextRole)
            return m_data.at(index.row()).text;
        return QVariant();
    }
    
    QHash<int, QByteArray> MyModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[NumberRole] = "number";
        roles[TextRole] = "text";
        return roles;
    }
    

    ma​​in.qml

    // ...
    TableView {
        width: 600
        height: 600
    
        model: myModel
        visible: true
    
        TableViewColumn {
            role: "number"
            title: "Number"
            width: 100
        }
        TableViewColumn {
            role: "text"
            title: "Text"
            width: 200
        }
    
        itemDelegate: Rectangle {
            color: "lightgray"
            width: 100
            height: 20
    
            Text {
                text: styleData.value
                color: "black"
            }
        }
    }
    // ...
    

    【讨论】:

    • 好的,谢谢你的信息。是的,我之前使用过 ListView 和 Repeaters,所以不想使用 TableViewColumn。我们有看起来非常适合 itemDelegate 的二维数据,但听起来 itemDelegate 直到 >= 5.12 才二维工作?是否有任何“视图”可以按照我描述的方式对具有单个委托的设置行/列进行二维工作?
    • @Tim 1) 问题与 itemDelegate 无关,但您的 Tableview 仅使用第一列。 2) 为什么不使用像我的示例中的列表类型模型? 3)没有这样的“视图”
    • 我会这样做,但我的领导同事不知道 Qt 不喜欢您不能为视图中的每个单元格使用单个委托的事实。它看起来像 GridView 一样,但它不是行/列驱动的,它似乎只是在布局,无论窗口有多大。我一直使用 ListView 和 Repeaters,遗憾的是对 QML 的 5.x 新版本几乎没有经验。
    • @Tim 1) GridView 是一个水平排列项目的视图,当没有更多空间时,就会创建一个新行。 2) 如果有人不了解 Qt,我觉得奇怪的是,他在决定 Qt 模型时拥有如此多的优势。 3) Qt 5.2 已经 6 岁了(我们已经在 Qt 5.14.2 中,Qt6 将在几个月后发布)所以它有很多限制(和错误),所以我建议更新你的 Qt 版本。 4) 一种可能的解决方案是使用代理。
    • 感谢您的所有建议,我真的很感激。我们目前停留在 Centos6 上,所以目前我们能做的最好的事情就是升级到 5.6.2 我相信。我同意你的cmets。您能进一步解释“代理”吗?我知道 QSortFilterProxyModel。那只是为了对列表进行排序?排序在这里不是问题。听起来你们俩都在说,在 Qt 的更高版本之前,我能做的最好的事情就是仅将内容放在列表中,并按行或列组织它们(就像我一直在做的那样),对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    相关资源
    最近更新 更多