qml TableView itemdelegate не срабатывает (с использованием QAbstractTableModel)

Я пытаюсь заставить свой первый QML TableView работать в Qt 5.2 (поскольку мы застряли на этой версии прямо сейчас на работе), используя QAbstractTableModel на бэкэнде.

Моя главная проблема заключается в том, что по какой-то причине itemDelegate никогда не срабатывает, поэтому я никогда не вижу ничего в представлении, кроме контура TableView. Я также проверил, что theData_ заполнен двумерными числами в каждой строке/столбце в конструкторе, и я делаю emit layoutChanged(), а также emit dataChanged() в конструкторе.

Я понимаю, что в настоящее время у меня нет проверки ошибок на недопустимый QModelIndex в вызове data().

Я тоже не реализовал 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]);
}

person Tim    schedule 23.04.2020    source источник


Ответы (1)


До Qt 5.12 существовал только компонент TableView, который принадлежит Qt QuickControl 1, который поддерживает только модель типа списка, где каждый столбец отражает информацию о роли, поэтому, вероятно, это ваша проблема, поскольку вы не создали ни одного TableViewColumn. С другой стороны, начиная с >= Qt5.12, другой TableView< /a> уже существует, и поддерживается как модель табличного типа.

моямодель.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

моямодель.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;
}

main.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"
        }
    }
}
// ...
person eyllanesc    schedule 23.04.2020
comment
Хорошо, спасибо за эту информацию. Да, раньше я использовал ListView и Repeaters, поэтому не хотел использовать TableViewColumn. У нас есть двумерные данные, которые кажутся идеальными для itemDelegate, но похоже, что itemDelegate не работает в двухмерном режиме до ›= 5.12? Есть ли какое-либо «представление», которое работает в двух измерениях для набора строк/столбцов с одним делегатом, как я описывал? - person Tim; 24.04.2020
comment
@Tim 1) Проблема не связана с itemDelegate, но в вашем Tableview используется только первый столбец. 2) Почему бы вам не использовать модель типа списка, как в моем примере? 3) Нет такого вида - person eyllanesc; 24.04.2020
comment
Я бы так и сделал, но моему коллеге, который является моим руководителем и не знает Qt, не нравится тот факт, что вы не можете использовать одного делегата для каждой ячейки в представлении. Похоже, что GridView делает это, но он не управляется строками/столбцами, просто кажется, что он выкладывается, каким бы большим ни было окно. Я всегда использовал ListView и Repeaters и, к сожалению, у меня мало опыта работы с более новыми версиями QML 5.x. - person Tim; 24.04.2020
comment
@Tim 1) GridView - это представление, которое упорядочивает элементы по горизонтали, и когда места больше нет, создается новая строка. 2) Если кто-то не знает о Qt, мне кажется странным, что у него такой перевес в решении о моделях Qt. 3) Qt 5.2 6 лет (у нас уже есть Qt 5.14.2, а Qt6 выйдет через несколько месяцев), поэтому у него много ограничений (и багов), поэтому я бы рекомендовал обновить вашу версию Qt. 4) Одним из возможных решений является использование прокси. - person eyllanesc; 24.04.2020
comment
Спасибо за все ваши советы, я очень ценю это. В настоящее время мы застряли на Centos6, поэтому лучшее, что мы можем сделать на данный момент, это обновить до 5.6.2, я думаю. Я согласен с вашими комментариями. Можете ли вы объяснить «прокси» подробнее? Я знаю о QSortFilterProxyModel. Это только для сортировки списка? Сортировка здесь не при чем. Похоже, вы оба говорите, что лучшее, что я могу сделать до более поздних версий Qt, — это размещать вещи только в списке и организовывать их по строкам или столбцам (как я делал все это время), верно? - person Tim; 24.04.2020