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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Перемещение строки в модели  (Прочитано 7391 раз)
aliks-os
Гость
« : Январь 27, 2011, 22:06 »

Есть модель наследованная от QStandardItemModel. В нее в цикле вносятся данные. Потом все это дело отображается в QTableView. Планирую на форме создать две кнопки, которые будут опускать/поднимать выделенную строку. Что то затупил и  не могу понять как сделать. Наставьте пожалуйста на пусть истинный
Записан
Kolobok
Гость
« Ответ #1 : Январь 27, 2011, 22:48 »

void QStandardItemModel::insertRow ( int row, const QList<QStandardItem *> & items )
QList<QStandardItem *> QStandardItemModel::takeRow ( int row )
Записан
blood_shadow
Гость
« Ответ #2 : Январь 27, 2011, 22:50 »

Есть модель наследованная от QStandardItemModel. В нее в цикле вносятся данные. Потом все это дело отображается в QTableView. Планирую на форме создать две кнопки, которые будут опускать/поднимать выделенную строку. Что то затупил и  не могу понять как сделать. Наставьте пожалуйста на пусть истинный
нажатие на кнопку -> передаешь в модель QAbstractItemView::currentIndex().row() (текущию выделенную строку) потом этот номер в модели меняешь местами с верхней/нижней строкой потом reset() для обновления представления
Записан
aliks-os
Гость
« Ответ #3 : Январь 27, 2011, 23:05 »

потом этот номер в модели меняешь местами с верхней/нижней строкой потом reset() для обновления представления

А об этом можно поподробнее, что то я не понимаю как можно сменить QModelIndex у эелемента
Записан
blood_shadow
Гость
« Ответ #4 : Январь 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;
Записан
aliks-os
Гость
« Ответ #5 : Январь 28, 2011, 00:13 »

Но в свойство row, а также column у QModelIndex насколько я понимаю "только для чтения"
Записан
blood_shadow
Гость
« Ответ #6 : Январь 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
Записан
aliks-os
Гость
« Ответ #7 : Январь 28, 2011, 00:33 »

затупил....примерчик можно как это на практике осуществить?
Записан
blood_shadow
Гость
« Ответ #8 : Январь 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" есть краткие примеры
Записан
aliks-os
Гость
« Ответ #9 : Январь 28, 2011, 00:57 »

Давай наверное и хидер для того чтобы спокойно разобраться
Записан
blood_shadow
Гость
« Ответ #10 : Январь 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
 
 
Записан
aliks-os
Гость
« Ответ #11 : Январь 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);
}
« Последнее редактирование: Январь 28, 2011, 13:06 от aliks-os » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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