Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: TreeModel + QSortFilterProxyModel + QTableView
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
edwardoid
Проблема такая:
Есть модель, наследующая QAbstractItemModel (ItemsModel). Она имеет древовидную структуру и используется в QTreeView. Нужно использовать ее через proxy(используется класс QSortFilterProxyModel(ItemsProxyModel)) в QTableView.

В искомой модели:
int ItemsModel::columnCount(const QModelIndex& parent) const
{
    return 1;
}


А в proxy модели, т.к. я исользую ее в QTableView мне нужны несколько колонок в которых будет разная информация из соответствующего item-a из оригинальной модели:
int ItemsProxyModel::columnCount(const QModelIndex& parent) const
{
    return 5;
}


Потому:
QVariant ItemsProxyModel::data(const QModelIndex& index, int role) const
{
    const int  r = index.row(),
                  c = index.column();
    QModelIndex itemIndex = itemIndex = this->index(r, 0, index.parent());
    itemIndex = mapToSource(itemIndex);
    ItemsModel model = dynamic_cast<ItemsModel*>(sourceModel());
    Item* item = model->getItem(itemIndex);
    if(role == Qt::DisplayRole)
    {
          if(c == 0)
          {
                return model->data(itemIndex, role);
          }
          return item->infoForColumn(c);
    }
    return QSortFilterProxyModel::data(index, role);
}


Я не знаю почему, но в функцию ItemsProxyModel::data(QModelIndex& index, int role) приходят индексы, в которых c < 1. Т.е не приходят индексы других колонок.
Вместе с тем QTreeView рисует таблицу с 5 столбцами(Которые нельзя пометить, они disabled).
Побовал переопределить Qt::ItemFlags QAbstractProxyModel::flags ( const QModelIndex & index ) const. Не помогло.

Вопрос: как мне добиться, чтобы и в других колонках показывалась нужная мне информация?
zoonman
QModelIndex itemIndex = itemIndex = this->index(r, 0, index.parent());


RTFM

QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const [pure virtual]
Returns the index of the item in the model specified by the given row, column and parent index.
edwardoid
Цитата(zoonman @ 27.6.2012, 22:58) *
QModelIndex itemIndex = itemIndex = this->index(r, 0, index.parent());


RTFM

QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const [pure virtual]
Returns the index of the item in the model specified by the given row, column and parent index.

И что? Проблема в том, что в функцию data приходят индексы только с column == 0



Гость
Во первых получаешь неверный item, а именно:
    QModelIndex realItemIndex = mapToSource(itemIndex);
    Item* item = model->getItem(realItemIndex );
    if(role == Qt::DisplayRole)
    {
          if(c == 0)
          {
                return model->data(realItemIndex , role);
          }
          return item->infoForColumn(c);
.
Но это так лирика, проблема в том, что ты не сделал свои реализации для mapToSource и mapFromSource.
Вот пример реализации прокси модели добавляющей одну чекабельную колонку к модели(атач гостям к сожалению не разрешен):
Хидер:
Раскрывающийся текст

#ifndef CHECKCOLUMNPROXY_H
#define CHECKCOLUMNPROXY_H

#include <QAbstractProxyModel>
class QStandardItemModel;
class CheckColumnProxy : public QAbstractProxyModel
{
    Q_OBJECT
public:
    explicit CheckColumnProxy(QObject *parent = 0);
    void setSourceModel(QAbstractItemModel *sourceModel);
    QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
    QModelIndex mapToSource(const QModelIndex &proxyIndex) const;

    QModelIndex index(int row,
                      int column,
                      const QModelIndex &parent =
               QModelIndex()) const;
    QModelIndex  parent(const QModelIndex &child) const;
    int rowCount(const QModelIndex &parent=QModelIndex()) const;
    int columnCount(const QModelIndex &parent=QModelIndex()) const;

    QVariant data(const QModelIndex &proxyIndex, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    Qt::ItemFlags flags(const QModelIndex &index) const;
public slots:
private:
    QStandardItemModel * m_checkModel;
    
};

#endif // CHECKCOLUMNPROXY_H


Сурс:
Раскрывающийся текст

#include "checkcolumnproxy.h"
#include <QStandardItemModel>
#include <QDebug>
#include <QItemSelection>

CheckColumnProxy::CheckColumnProxy(QObject *parent) :
    QAbstractProxyModel(parent), m_checkModel(new QStandardItemModel(this))
{
    m_checkModel->setColumnCount(1);
}

void CheckColumnProxy::setSourceModel(QAbstractItemModel *sourceModel)
{
    QAbstractProxyModel::setSourceModel(sourceModel);
    m_checkModel->setRowCount(0);
    m_checkModel->setRowCount(sourceModel->rowCount());
    for(int i = 0; i < m_checkModel->rowCount(); i++)
    {
        QStandardItem * item = new QStandardItem("ololo");
        item->setCheckable(true);
        item->setEnabled(true);
        item->setEditable(true);
        item->setSelectable(true);
        m_checkModel->setItem(i,0,item);
    }

}


QModelIndex CheckColumnProxy::mapToSource(const QModelIndex &proxyIndex) const
{

    if(proxyIndex.column() > 0)
    {
        return sourceModel()->index(proxyIndex.row(), proxyIndex.column() - 1);
    }
    QModelIndex i = m_checkModel->index(proxyIndex.row(), proxyIndex.column());
    return i;
}


QModelIndex CheckColumnProxy::index(int row, int column, const QModelIndex &parent) const
{
    if(parent.isValid())return QModelIndex();
    return createIndex(row, column);
}

QModelIndex CheckColumnProxy::parent(const QModelIndex &/*child*/) const
{
    return QModelIndex();
}

int CheckColumnProxy::rowCount(const QModelIndex &parent) const
{
    if(parent.isValid() || !sourceModel()) return 0;
    return sourceModel()->rowCount();
}

int CheckColumnProxy::columnCount(const QModelIndex &parent) const
{
    if(parent.isValid() || !sourceModel()) return 0;
    return sourceModel()->columnCount() + 1;
}

QVariant CheckColumnProxy::data(const QModelIndex &proxyIndex, int role) const
{
    if(proxyIndex.column()>0)
        return QAbstractProxyModel::data(proxyIndex, role);
    QVariant data = m_checkModel->item(proxyIndex.row(),0)->data(role);
    qDebug()<<role<<"-"<<data;
    return data;
}

bool CheckColumnProxy::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(index.column() > 0)
    {
        return QAbstractProxyModel::setData(index, value, role);

    }
    qDebug()<<"Set "<< value;
    return m_checkModel->setData(m_checkModel->index(index.row(),0), value, role);

}

Qt::ItemFlags CheckColumnProxy::flags(const QModelIndex &index) const
{
    if(index.column()>0)
        return QAbstractProxyModel::flags(index);
    else
        return m_checkModel->flags(mapToSource(index));
}


QModelIndex CheckColumnProxy::mapFromSource(const QModelIndex &sourceIndex) const
{
    return this->index(sourceIndex.row(), sourceIndex.column());
}



Это правда вариант на коленке, который я кому то опять же в учебных целях делал, но основную идею иллюстрирует.
Гость
Упс, за Item сорри не разглядел, просто часто нераспространенная ошибка.
Гость
* часто распостраненная
Лол лучше пойду пить кофе.

Большой синий букв М последним 2ум мессаджам и первую часть поста подредактируйте если не сложно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2020 IPS, Inc.