Russian Qt Forum

Qt => Общие вопросы => Тема начата: demaker от Сентябрь 17, 2013, 12:05



Название: [Решено]Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 12:05
Подскажите, возможно ли обновление модели, но так чтобы
итемы в ней не сворачивались???
А то если добавляешь элемент в модель, надо заново разворачивать ее с корня, это не удобно.


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 12:07
делать не beginResetModel(), а beginInsertRows() при добавлении элемента


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 12:21
делать не beginResetModel(), а beginInsertRows() при добавлении элемента

А данные???
Или они автоматически подтянуться?


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 12:22
Что "а данные"? Не понял вопроса


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 12:29
При формирование модели
Код:
QVariant ModelBrowser::data(const QModelIndex &index, int role) const

c ее помощью мы отображаем данные.

А когда я добавил элемент в модель, то данные автоматически подтянуться?


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 12:30
опять ниче не понял. Куда подтянутся?


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 12:33
В модель


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 12:37
нет, в модель ты их должен добавить сам, как и до этого. Но вместо beginResetModel()/endResetModel() надо использовать beginInsertRows()/endInsertRows() для оповещения view


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 12:49
Классно
т.е
Код:
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last )
просто добавляет строчку
а индекс, и все прочее делайте сами


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 12:55
Он не добавляет строчку, он извещает вью о том, что в модель добавились данные


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 13:13
сделал вот так
Код
C++ (Qt)
void TreeModelBrowser::updateModel(QModelIndex index)
{
   int row =  rowCount(index);
   row++;
   beginInsertRows(index,row,row);
   endInsertRows();
}
 
все бы ничего
только

TreeModelBrowser имеет древовидную структуру
и прежде чем у меня добавленный элемент модели у меня отображается во view
нужно свернуть все дерево, а потом заново его раскрыть.


Название: Re: Обновление модели
Отправлено: Bepec от Сентябрь 17, 2013, 13:17
Гы...

Begin
// действия с данными
End


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 13:23
Гы...

Begin
// действия с данными
End
Код
C++ (Qt)
QVariant TreeModelBrowser::data(const QModelIndex &index, int role) const
{
   QObject*obj;
   if(!index.isValid())
       obj = base;
   else
       obj = reinterpret_cast<QObject*>(index.internalPointer());
 
   if(role == Qt::DisplayRole)
   {
       if(index.column() == 0 && QVariant(obj->metaObject()->className()).toString() == "Base")
       {
           Base*b =  dynamic_cast<Base*>(obj);
           return b->str;
       }
       if(index.column() == 1 && QVariant(obj->metaObject()->className()).toString() == "Station")
       {
           Station*s =  dynamic_cast<Station*>(obj);
           return s->str;
       }
       else  if(index.column() == 2 && QVariant(obj->metaObject()->className()).toString() == "Device")
       {
           Device*d =  dynamic_cast<Device*>(obj);
           return d->str;
       }
     return QVariant();
}
 

Это не будет работать?


Название: Re: Обновление модели
Отправлено: Bepec от Сентябрь 17, 2013, 13:38
Кхм. Возможно вы что-то не понимаете в model-view.

data будет работать.

Чтобы View адекватно реагировало на изменение данных в модели необходимо извещать view об изменениях.

Специально для этого есть пары функции beginInsertRows/Columns, beginRemoveColumns/Rows.
Собственно операции нужно производить в промежутке между begin и end.

Код:
//Вставляем данные в модель
void insert(QString data)
{
// Оповещаем view о том, что будет вставлено N записей.
beginInsertRows(*);
// далее добавляем в хранилище, допустим будет listData_
listData.append(data);
// Оповещаем view о том, что данные можно забирать
endInsertRows();
}

PS или я опять вас не так понял. Тогда что со мной твориться О_о


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 13:42
сделал вот так
Код
C++ (Qt)
void TreeModelBrowser::updateModel(QModelIndex index)
{
   int row =  rowCount(index);
   row++;
   beginInsertRows(index,row,row);
   endInsertRows();
}
 
все бы ничего
только

TreeModelBrowser имеет древовидную структуру
и прежде чем у меня добавленный элемент модели у меня отображается во view
нужно свернуть все дерево, а потом заново его раскрыть.

Я вот не вижу тут никакого нового элемента


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 13:57
Сделал вот так
Код
C++ (Qt)
void TreeModelBrowser::updateModel1(QModelIndex index)
{
   int row =  rowCount(index);
   row++;
   beginInsertRows(index,row,row);
   CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
   ce->appendChild();
   endInsertRows();
}
 

но тот же эффект... ???


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 14:02
наверно внутри ce->appendChild(); скрыта какая-то магия, недоступная нам


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 14:03
наверно внутри ce->appendChild(); скрыта какая-то магия, недоступная нам

оч смешно


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 14:03
смешно то, что ты почему-то думаешь, что мы все знаем что же происходит внутри ce->appendChild();

Ну и reinterpret_cast это очень опасно в таком случае, потому что никаких проверок при этом не происходит


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 14:11
Код:
class CommonElement: public QObject
{
    Q_OBJECT

public:
    explicit CommonElement(QObject*parent = 0);
    virtual ~CommonElement();

    virtual CommonElement* appendChild() = 0;
    virtual void removeChild(CommonElement*) = 0;
    virtual void function() = 0;

public:
    QString str;
    QList<CommonElement*> listChildren;
};



Код:
class Station: public CommonElement
{
    Q_OBJECT

public:
    explicit Station(CommonElement *parent = 0);
    virtual ~Station();

    CommonElement* appendChild();
    void removeChild(CommonElement *);
    void function();
};




Station::Station(CommonElement *parent):
  CommonElement(parent)
{
    str = "MyStantion";
}

Station::~Station()
{
}

CommonElement* Station::appendChild()
{
    Device *device = new Device(this);
    listChildren.append(device);
    return device;
}

void Station::removeChild(CommonElement *device)
{
    listChildren.removeOne(device);
    delete device;
}

void Station::function()
{
    qDebug()<<"Station->str = " + str;
}




Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 14:26
С использованием resetModel у тебя это вот добавление работает?


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 14:32
Да


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 17, 2013, 14:34
Покажи код, который добавляет элемент и выполняет resetModel


Название: Re: Обновление модели
Отправлено: demaker от Сентябрь 17, 2013, 14:44
Покажи код, который добавляет элемент и выполняет resetModel

Код
C++ (Qt)
...
connect(treeview,SIGNAL(clicked(QModelIndex)),this,SLOT(clickedTreeView(QModelIndex)));
connect(this,SIGNAL(appendChild(QModelIndex)),treemodel,SLOT(updateModel(QModelIndex)));
...
void MainWindow::appendElement()
{
   qDebug()<<"appendElement";
   if(currentElement != NULL)
   {
       Q_EMIT appendChild(currentModelIndex);
   }
}
 
void MainWindow::clickedTreeView(QModelIndex index)
{
   if(index.isValid())
   {
       currentModelIndex = index;
       currentElement = reinterpret_cast<CommonElement*>(currentModelIndex.internalPointer());
       listmodel->setRoot(currentElement);
       setPathLabel(currentElement);
   }
}
 
 

Код
C++ (Qt)
void TreeModelBrowser::updateModel(QModelIndex index)
{
   if(index.isValid())
   {    
       beginResetModel();
       CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
       ce->appendChild();
       endResetModel();
   }
}
 


Название: Re:[Решено] Обновление модели
Отправлено: demaker от Сентябрь 18, 2013, 10:53
Как код? Правильный или нет???


Название: Re: Обновление модели
Отправлено: mutineer от Сентябрь 18, 2013, 10:59
Если добавление работает корректно, то по идее достаточно заменить beginResetModel()/endResetModel() на beginInsertRows()/endInsertRows()