crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> TreeModel + QSortFilterProxyModel + QTableView
edwardoid
  опции профиля:
сообщение 26.6.2012, 11:20
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 171
Регистрация: 1.5.2008
Из: Ереван, Армения
Пользователь №: 164

Спасибо сказали: 0 раз(а)




Репутация:   0  


Проблема такая:
Есть модель, наследующая 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. Не помогло.

Вопрос: как мне добиться, чтобы и в других колонках показывалась нужная мне информация?

Сообщение отредактировал edwardoid - 27.6.2012, 23:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zoonman
  опции профиля:
сообщение 27.6.2012, 21:58
Сообщение #2


Студент
*

Группа: Новичок
Сообщений: 18
Регистрация: 24.1.2011
Пользователь №: 2361

Спасибо сказали: 0 раз(а)




Репутация:   0  


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
  опции профиля:
сообщение 27.6.2012, 23:43
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 171
Регистрация: 1.5.2008
Из: Ереван, Армения
Пользователь №: 164

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(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



Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 28.6.2012, 9:49
Сообщение #4





Гости








    


Во первых получаешь неверный 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());
}



Это правда вариант на коленке, который я кому то опять же в учебных целях делал, но основную идею иллюстрирует.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 28.6.2012, 9:55
Сообщение #5





Гости








    


Упс, за Item сорри не разглядел, просто часто нераспространенная ошибка.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 28.6.2012, 9:58
Сообщение #6





Гости








    


* часто распостраненная
Лол лучше пойду пить кофе.

Большой синий букв М последним 2ум мессаджам и первую часть поста подредактируйте если не сложно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.3.2024, 18:28