Russian Qt Forum
Ноябрь 01, 2024, 16:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Transposeproxymodel - поясните реакцию на изменение данных  (Прочитано 6163 раз)
neosapient
Гость
« : Декабрь 29, 2009, 00:01 »

Есть пример Transposeproxymodel (взял из интернета).

Помогите объясниться странное поведение?
- Если  изменить ячейку левой таблицы, то соответствующая ячейка правой таблицы получит значение только если с левой таблицы убрать фокус.
- Если изменить ячейку правой таблицы,  то соответствующая ячейка левой таблицы получит значение моментально

Что следует изменить, чтобы обе таблицы модифицировались моментально ?
Код:
#include <QApplication>
#include <QStandardItemModel>
#include <QAbstractProxyModel>
#include <QTableView>
#include <QSplitter>

class TransposeProxyModel : public QAbstractProxyModel{
public:
  TransposeProxyModel(QObject *p = 0) : QAbstractProxyModel(p){}
  QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const{
    return index(sourceIndex.column(), sourceIndex.row());
  }
  QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const{
    return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
  }
  QModelIndex index(int r, int c, const QModelIndex &ind=QModelIndex()) const{
    return createIndex(r,c);
  }
  QModelIndex parent(const QModelIndex&) const {
    return QModelIndex();
  }
  int rowCount(const QModelIndex &) const{
    return sourceModel()->columnCount();
  }
  int columnCount(const QModelIndex &) const{
    return sourceModel()->rowCount();
  }
  QVariant data(const QModelIndex &ind, int role) const {
    return sourceModel()->data(mapToSource(ind), role);
  }
};


int main(int argc, char **argv){
  QApplication app(argc, argv);
  QStandardItemModel model(3,3);
  model.setData(model.index(0,0), "1");
  model.setData(model.index(0,1), "2");
  model.setData(model.index(0,2), "3");
  model.setData(model.index(1,0), "4");
  model.setData(model.index(1,1), "5");
  model.setData(model.index(1,2), "6");
  model.setData(model.index(2,0), "7");
  model.setData(model.index(2,1), "8");
  model.setData(model.index(2,2), "9");
  TransposeProxyModel trans;
  trans.setSourceModel(&model);
  QSplitter split;
  QTableView *t1 = new QTableView(&split);
  t1->setModel(&model);
  QTableView *t2 = new QTableView(&split);
  t2->setModel(&trans);
  split.show();
  return app.exec();
}
Записан
Marat(Qt)
Гость
« Ответ #1 : Декабрь 29, 2009, 21:11 »

Не особо вник, но я бы сделал так:
Код:
  TransposeProxyModel trans1,trans2;
  trans1.setSourceModel(&model);
  trans2.setSourceModel(&model);
  QSplitter split;
  QTableView *t1 = new QTableView(&split);
  t1->setModel(&trans1);
  QTableView *t2 = new QTableView(&split);
  t2->setModel(&trans2);
Записан
Sergeich
Гость
« Ответ #2 : Январь 05, 2010, 16:50 »

Дело в том, что при изменении исходной модели прокси-модель не оповещает свои представления об этих изменениях. Простейший вариант как это сделать:
Код:
#include <QApplication>
#include <QStandardItemModel>
#include <QAbstractProxyModel>
#include <QTableView>
#include <QSplitter>

class TransposeProxyModel : public QAbstractProxyModel
{
Q_OBJECT

public:
TransposeProxyModel(QObject *p = 0) : QAbstractProxyModel(p) {}

QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const {
return index(sourceIndex.column(), sourceIndex.row());
}

QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const {
return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
}

QModelIndex index( int r, int c, const QModelIndex& idx = QModelIndex() ) const {
Q_UNUSED(idx)
return createIndex( r, c );
}

QModelIndex parent( const QModelIndex& ) const {
return QModelIndex();
}

int rowCount( const QModelIndex & ) const{
return sourceModel()->columnCount();
}

int columnCount( const QModelIndex & ) const{
return sourceModel()->rowCount();
}

QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const {
Qt::Orientation srcOrient = ( orientation == Qt::Vertical ) ? Qt::Horizontal :  Qt::Vertical;
return sourceModel()->headerData( section, srcOrient, role );
}

void setSourceModel( QAbstractItemModel * srcModel ) {
QAbstractProxyModel::setSourceModel( srcModel );
connect( srcModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
this, SLOT(onSourceDataChanged(QModelIndex, QModelIndex)) );
}

protected slots:

void onSourceDataChanged( const QModelIndex& topLeft, const QModelIndex& botRight ) {
emit dataChanged( mapFromSource(topLeft), mapFromSource(botRight) );
}
};


int main( int argc, char **argv )
{
QApplication app(argc, argv);

const int nRow = 5;
const int nCol = 4;
QStandardItemModel model( nRow, nCol );
for ( int row = 0; row < nRow; ++row ) {
model.setHeaderData( row, Qt::Vertical, QString('A' + row) );
for ( int col = 0; col < nCol; ++col )
model.setData( model.index( row, col ), nCol * row + col + 1 );
}

TransposeProxyModel trans;
trans.setSourceModel(&model);

QSplitter split;
QTableView *srcView = new QTableView(&split);
srcView->setModel(&model);
QTableView *transView = new QTableView(&split);
transView->setModel(&trans);
split.show();
return app.exec();
}

#include "main.moc"
Аналогично нужно обрабатывать изменение данных заголовков и вставку/удаление строк/столбцов
Записан
Dp0H
Гость
« Ответ #3 : Январь 27, 2010, 11:37 »

Как раз хотел тему создавать Улыбающийся
Цитировать
Дело в том, что при изменении исходной модели прокси-модель не оповещает свои представления об этих изменениях.
Тоже при модификации модели данных представление не хочет обновляться, если показывает через прокси (пока не ткнешь мышью в представление).
Неужели для пересылки dataChanged надо делать своего наследника от прокси-модели?!  Шокированный
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 21.