Название: Перемещение строки в модели
Отправлено: aliks-os от Январь 27, 2011, 22:06
Есть модель наследованная от QStandardItemModel. В нее в цикле вносятся данные. Потом все это дело отображается в QTableView. Планирую на форме создать две кнопки, которые будут опускать/поднимать выделенную строку. Что то затупил и не могу понять как сделать. Наставьте пожалуйста на пусть истинный
Название: Re: Перемещение строки в модели
Отправлено: Kolobok от Январь 27, 2011, 22:48
void QStandardItemModel::insertRow ( int row, const QList<QStandardItem *> & items ) QList<QStandardItem *> QStandardItemModel::takeRow ( int row )
Название: Re: Перемещение строки в модели
Отправлено: blood_shadow от Январь 27, 2011, 22:50
Есть модель наследованная от QStandardItemModel. В нее в цикле вносятся данные. Потом все это дело отображается в QTableView. Планирую на форме создать две кнопки, которые будут опускать/поднимать выделенную строку. Что то затупил и не могу понять как сделать. Наставьте пожалуйста на пусть истинный
нажатие на кнопку -> передаешь в модель QAbstractItemView::currentIndex().row() (текущию выделенную строку) потом этот номер в модели меняешь местами с верхней/нижней строкой потом reset() для обновления представления
Название: Re: Перемещение строки в модели
Отправлено: aliks-os от Январь 27, 2011, 23:05
потом этот номер в модели меняешь местами с верхней/нижней строкой потом reset() для обновления представления
А об этом можно поподробнее, что то я не понимаю как можно сменить QModelIndex у эелемента
Название: Re: Перемещение строки в модели
Отправлено: blood_shadow от Январь 27, 2011, 23:57
потом этот номер в модели меняешь местами с верхней/нижней строкой потом reset() для обновления представления
А об этом можно поподробнее, что то я не понимаю как можно сменить QModelIndex у эелемента так ты индекс не меняешь ты меняешь просто содержимое индекса, то есть если модель хранит где-то так на правах псевдокода: QList<QList<QString> >; c = QList.at(i); QList.at(i) = QList.at(i+1); QList.at(i+1) = c;
Название: Re: Перемещение строки в модели
Отправлено: aliks-os от Январь 28, 2011, 00:13
Но в свойство row, а также column у QModelIndex насколько я понимаю "только для чтения"
Название: Re: Перемещение строки в модели
Отправлено: blood_shadow от Январь 28, 2011, 00:28
Но в свойство row, а также column у QModelIndex насколько я понимаю "только для чтения"
так тебе и ненадо ров и колимн трогать тебе надо только внутри модели поменять местами данные, а представление уже само отобразит их в заданном порядке с помощью ф-ции data() например если ты хранишь каждую строку в списке, а все данные в родительском списке, то необходимо узнать какой список с каким менять, например у меня родительский список указателей на объекты хранит указатели на созданные объекты-строки, в конструкторе модели я заполняю род. список нулями, и потом при создании объекта-строки, я его пихаю в заданный порядок, например: допустим заполнены строка 7 и 8, род.список будет тогда выглядеть: 0 0 0 0 0 0 0 ук1 ук2 0 0 и т.д, представление отображает объект по адресу ук1 или ук2 в зависимости от строчки, и потому я меняю местами ук2 ук1 и получаю продвижение строчки ук2
Название: Re: Перемещение строки в модели
Отправлено: aliks-os от Январь 28, 2011, 00:33
затупил....примерчик можно как это на практике осуществить?
Название: Re: Перемещение строки в модели
Отправлено: blood_shadow от Январь 28, 2011, 00:47
затупил....примерчик можно как это на практике осуществить?
программа громадная кину по частях: реализация модели C++ (Qt) #include "tableModel.h" #include "tableRepository.h" #include <QtGui> #include <QFile> #include <QStringList> #include <QDebug> #include <Analysis_of_accidents.h> #define ADIITIONAL_ROWS 10 AccidentModelTable::AccidentModelTable(int rows, QWidget *parent) : QAbstractTableModel(parent), tableColumnCount(60), tableRowCount(rows) { p_parentObj = dynamic_cast<Analysis_of_accidents* > (parent); if (!p_parentObj) qDebug() << "Error cast in AccidentModelTable::AccidentModelTable"; p_tableDataRepositoryVector = new QVector<Data::TableDataRepository* > (tableRowCount); // fill all vector to default value "0" - it's indicate free space in vector p_tableDataRepositoryVector->fill(0); dataCounter = 0; tableTitle = new QStringList; qDebug() << "In Model"; connect(this, SIGNAL(dataCounterChanged()), this, SLOT(tableNeedRow())); } // ****** Realization Function for MVC int AccidentModelTable::rowCount(const QModelIndex &parent) const { return tableRowCount; } int AccidentModelTable::columnCount(const QModelIndex &parent) const { return tableColumnCount; } QVariant AccidentModelTable::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::TextAlignmentRole) { return int(Qt::AlignCenter); } else if (role == Qt::DisplayRole && p_tableDataRepositoryVector->at(index.row())) { if (index.row() == p_tableDataRepositoryVector->at(index.row())->get_tablePlacementRowIdentifier()) return p_tableDataRepositoryVector->at(index.row())->At(index.column()); } return QVariant(); } bool AccidentModelTable::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && role == Qt::EditRole) { qDebug() << "In setData Func"; emit dataChanged(index, index); return true; } return false; } Qt::ItemFlags AccidentModelTable::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; } QVariant AccidentModelTable::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { if (orientation == Qt::Horizontal) return tableTitle->at(section); else return section + 1; } return QVariant(); } // store Data Object void AccidentModelTable::setDataObjectToVector(Data::TableDataRepository* dataObj) { // if Data in such row exists input a QMessage dialog if ((*p_tableDataRepositoryVector)[dataObj->get_tablePlacementRowIdentifier()]) { bool result = p_parentObj->IsToContinueRewrite(); // if user click rewrite destroy old object and put new, else return if (result) p_parentObj->destroyDataRepositoryObject((*p_tableDataRepositoryVector) [dataObj->get_tablePlacementRowIdentifier()]); else { p_parentObj->destroyDataRepositoryObject(dataObj); return; } } (*p_tableDataRepositoryVector)[dataObj->get_tablePlacementRowIdentifier()] = dataObj; incrementDataCounter(); // emits when data object counter changed emit dataCounterChanged(); qDebug() << "Data Counter" << getDataCounter(); reset(); return; } // remove Data Object bool AccidentModelTable::ClearRow(int row) { // return from function if user click on empty row if (!(*p_tableDataRepositoryVector)[row]) return false; // delete current Object p_parentObj->destroyDataRepositoryObject((*p_tableDataRepositoryVector)[row]); (*p_tableDataRepositoryVector)[row] = 0; // update Table View emit dataChanged(index(row, 0), index(row, tableColumnCount - 1)); return true; } int AccidentModelTable::columnCount() const { return tableColumnCount; } // operate with data object counter void AccidentModelTable::incrementDataCounter() { ++dataCounter; } void AccidentModelTable::decrementDataCounter() { --dataCounter; } uint AccidentModelTable::getDataCounter() { return dataCounter; } void AccidentModelTable::tableNeedRow() { if (getDataCounter() >= tableRowCount - 3) insertRows(tableRowCount, ADIITIONAL_ROWS); qDebug() << "Vector size -> " << p_tableDataRepositoryVector->size(); } bool AccidentModelTable::insertRows(int position, int rows, const QModelIndex &parent) { beginInsertRows(QModelIndex(), position, position+rows-1); // put ten 0 - pointers to the end of vector for (int row = 0; row < rows; ++row) p_tableDataRepositoryVector->append(0); endInsertRows(); // Add more rows to Table tableRowCount += rows; return true; }
обрати внимание на конструктор и ф-цию data p_tableDataRepositoryVector - указатель на вектор где я храню объекты-строки если надо могу и хэдер кинуть а вообще посмотри в ассистанте там в разделе "An Introduction to Model/View Programming" есть краткие примеры
Название: Re: Перемещение строки в модели
Отправлено: aliks-os от Январь 28, 2011, 00:57
Давай наверное и хидер для того чтобы спокойно разобраться
Название: Re: Перемещение строки в модели
Отправлено: blood_shadow от Январь 28, 2011, 01:00
Давай наверное и хидер для того чтобы спокойно разобраться
C++ (Qt) #ifndef TABLEWIDGET_H #define TABLEWIDGET_H #include <tableRepository.h> #include <QAbstractTableModel> class QStringList; class Analysis_of_accidents; class AccidentModelTable : public QAbstractTableModel { Q_OBJECT int tableRowCount; const int tableColumnCount; // pointer to Parent object of Analysis_of_accidents class Analysis_of_accidents* p_parentObj; // vector for storing TableDataRepository objects in it QVector<Data::TableDataRepository* >* p_tableDataRepositoryVector; // save count of filled rows uint dataCounter; // header titles QStringList* tableTitle; public: explicit AccidentModelTable(int rows, QWidget *parent = 0); //void clear(int rowCount); // **** Function which used in MVC int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; // store Data Object in vector void setDataObjectToVector(Data::TableDataRepository* dataObj); // remove Data Object from vector bool ClearRow(int row); int columnCount() const; //increment or decrement object data counter void incrementDataCounter(); void decrementDataCounter(); uint getDataCounter(); // insert empty rows bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); // Count of columns depending on Title int ColumnCount; private: enum {MagicNumber = 0x3F871A2}; private slots: void tableNeedRow(); //void somethingChanged(); signals: void dataCounterChanged(); //void modified(); }; #endif // TABLEWIDGET_H
Название: Re: Перемещение строки в модели
Отправлено: aliks-os от Январь 28, 2011, 12:41
void QStandardItemModel::insertRow ( int row, const QList<QStandardItem *> & items ) QList<QStandardItem *> QStandardItemModel::takeRow ( int row )
Спасибо, ваша подсказка помогла. В модели реализовал вот таким образом QModelIndex MyModel::moveRow(const Movement &moveTo, const QModelIndex &idx) { int newRow = idx.row(); if (moveTo == moveUp && idx.row() != 0) newRow = idx.row()-1; if (moveTo == moveDown && idx.row() < this->rowCount()-1) newRow = idx.row()+1; QList<QStandardItem *> lst = this->takeRow(idx.row()); this->insertRow(newRow, lst);
QModelIndex newIdx = this->index(newRow,idx.column()); return newIdx; }
а управлением - таким void TableEditWindow::moveRow() { MyModel *m = qobject_cast<MyModel *>(ui->table_fields->model()); QModelIndex newIdx; if (sender()->objectName() == "btnUp") { newIdx = m->moveRow(moveUp, ui->table_fields->currentIndex()); } if (sender()->objectName() == "btnDown") { newIdx = m->moveRow(moveDown, ui->table_fields->currentIndex()); } ui->table_fields->setCurrentIndex(newIdx); }
|