Russian Qt Forum

Qt => Вопросы новичков => Тема начата: demaker от Март 21, 2014, 11:39



Название: Model-View
Отправлено: demaker от Март 21, 2014, 11:39
Добавляю элементы в модель
Но почему-то иногда это выполняется сразу нормально,а иногда нет.
Скажите ниже приведенный код правильный или нет?
Код
C++ (Qt)
void TreeModelBrowser::updateModelInsertRow(QModelIndex index)
{
   if(index.isValid())
   {
       int row = index.row();
       row++;
       beginInsertRows(index,row,row);
       CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
       ce->appendChild();    
       endInsertRows();
 
       qDebug()<<"TreeModelBrowser::updateModelInsertRow";
 
   }
}
 
void TreeModelBrowser::updateModelRemoveRow(QModelIndex index)
{
   if(index.isValid())
   {
       int row = index.row();
       QModelIndex parentIndex = index.parent();
       beginRemoveRows(parentIndex,row,row);
       CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
       delete ce;
       endRemoveRows();
   }
}
 


Название: Re: Model-View
Отправлено: UltraPenguin от Март 24, 2014, 09:58
Я думаю было бы проще Вам подсказать, если было бы уточнение фразы
Цитировать
иногда это выполняется сразу нормально,а иногда нет.
а также что делают функции
Код:
beginInsertRows(index,row,row);
и
Код:
endInsertRows();


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 11:34
а также что делают функции
Код:
beginInsertRows(index,row,row);
и
Код:
endInsertRows();

Код:
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last ) [protected]

Begins a row insertion operation.
When reimplementing insertRows() in a subclass, you must call this function before inserting data into the model's underlying data store.
The parent index corresponds to the parent into which the new rows are inserted; first and last are the row numbers that the new rows will have after they have been inserted.


void QAbstractItemModel::endInsertRows () [protected]

Ends a row insertion operation.
When reimplementing insertRows() in a subclass, you must call this function after inserting data into the model's underlying data store.


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 13:22
Цитировать
иногда это выполняется сразу нормально,а иногда нет.

Т.е я хочу добавить в модель еще один элемент, но чтобы не перезагружать ее (т.е без reset());
Чтобы не тыкать лишний раз на указатель вложенности(стрелочка);
Но это не каждый раз срабатывает.
Элемент добавляется, но не отображается в окне.


Название: Re: Model-View
Отправлено: Bepec от Март 24, 2014, 14:31
С высоты своего опыта скажу, "не работает". Точнее не у вас всё плохо проходит, а просто ваше "добавление" совпадает с каким-то сигналом обновления View :)


Название: Re: Model-View
Отправлено: Igors от Март 24, 2014, 14:52
А так пробовали?
Код
C++ (Qt)
void TreeModelBrowser::updateModelInsertRow( const QModelIndex & index )
{
   if(index.isValid())
   {
       CommonElement *ce = dynamic_cast<CommonElement*>(index.internalPointer());
       if (ce)
         ce->appendChild();    
       else
         Q_ASSERT(0);  
   }
}


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 14:57
А так пробовали?
Код
C++ (Qt)
void TreeModelBrowser::updateModelInsertRow( const QModelIndex & index )
{
   if(index.isValid())
   {
       CommonElement *ce = dynamic_cast<CommonElement*>(index.internalPointer());
       if (ce)
         ce->appendChild();    
       else
         Q_ASSERT(0);  
   }
}

Попробовал, но не помогает


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 15:12
С высоты своего опыта скажу, "не работает". Точнее не у вас всё плохо проходит, а просто ваше "добавление" совпадает с каким-то сигналом обновления View :)

И что делать?


Название: Re: Model-View
Отправлено: Old от Март 24, 2014, 15:22
И что делать?
Странно. Попробуйте для проверки другой View использовать, например, QTableView.
У меня модели обновляются асинхронно, при изменении SQL-таблиц. Вроде всегда все нормально было.


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 15:43
И что делать?
Странно. Попробуйте для проверки другой View использовать, например, QTableView.
У меня модели обновляются асинхронно, при изменении SQL-таблиц. Вроде всегда все нормально было.

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


Название: Re: Model-View
Отправлено: Old от Март 24, 2014, 15:52
??? Смысл другой view ?
Смысл в том, что у меня все работает: строки появляются, обновляются, удаляются.
Модели - свои, в качестве гляделки используется QTableView.

Вот я вам и предлагаю набросать простую модель и погонять его с разными гляделками, что бы понять, кто неправ - вы или Qt. :)


Название: Re: Model-View
Отправлено: Bepec от Март 24, 2014, 15:55
Я давно свои модели крутил, помню что там задача в beginInsertRows правильном. Поиграйтесь с индексом и строками.


Название: Re: Model-View
Отправлено: _OLEGator_ от Март 24, 2014, 15:59
Код
C++ (Qt)
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last ) [protected]
Судя по коду ты неправильно задаешь parent в функции updateModelInsertRow, причем в updateModelRemoveRow ты используешь корректный parent:
Код
C++ (Qt)
QModelIndex parentIndex = index.parent();


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 16:21
Код
C++ (Qt)
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last ) [protected]
Судя по коду ты неправильно задаешь parent в функции updateModelInsertRow, причем в updateModelRemoveRow ты используешь корректный parent:
Код
C++ (Qt)
QModelIndex parentIndex = index.parent();

т.е надо делать так

Код
C++ (Qt)
void TreeModelBrowser::updateModelInsertRow(QModelIndex index)
{
   if(index.isValid())
   {        
       CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
       QModelIndex parentIndex = index.parent();        
       int row = index.row();
       row++;
       beginInsertRows(parentIndex,row,row);
       ce->appendChild();
       endInsertRows();
 
       qDebug()<<"TreeModelBrowser::updateModelInsertRow";
   }
}
 

Но почему? Ведь я добавляю элемент, и парентом уже является  
Код:
CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
и индекс парента
Код:
 
index
Или нет???
Объясните пожалуйста :)


Название: Re: Model-View
Отправлено: _OLEGator_ от Март 24, 2014, 16:30
Это я тебе должен объяснять, как работает твой код?
Ты мне лучше объясни, почему в одном случае используешь QModelIndex parentIndex = index.parent(), а в другом нет, хотя функции beginInsertRows и beginRemoveRows имеют одинаковую сигнатуру и одинаково требуют parent в качестве первого параметра.


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 16:39
Это я тебе должен объяснять, как работает твой код?
Ты мне лучше объясни, почему в одном случае используешь QModelIndex parentIndex = index.parent(), а в другом нет, хотя функции beginInsertRows и beginRemoveRows имеют одинаковую сигнатуру и одинаково требуют parent в качестве первого параметра.

Да, действительно помогло. Спасибо!
В void TreeModelBrowser::updateModelInsertRow(QModelIndex index)
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент и я думал, что он является парентом.


Название: Re: Model-View
Отправлено: Old от Март 24, 2014, 16:48
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент и я думал, что он является парентом.
Какая то у вас здесь не стыковка. :)
Если вы хотите добавить child к текущему элементу, то индекс этого элемента нужно передавать в качестве parent.

A
B
    B1
        // Добавляем B11 - parent это B1, row = 0
    B2
    B3
C

Если вы хотите добавить элемент после текущего к его родителю, то передавать нужно parent родителя этого элемента.

A
B
    B1
    B2
    // Добавляем элемент B3 - parent это элемент B, row = 2
C


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 17:00
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент и я думал, что он является парентом.
Какая то у вас здесь не стыковка. :)
Если вы хотите добавить child к текущему элементу, то индекс этого элемента нужно передавать в качестве parent.

A
B
    B1
        // Добавляем B11 - parent это B1, row = 0
    B2
    B3
C

Если вы хотите добавить элемент после текущего к его родителю, то передавать нужно parent родителя этого элемента.

A
B
    B1
    B2
    // Добавляем элемент B3 - parent это элемент B, row = 2
C


А у меня как?


Название: Re: Model-View
Отправлено: Old от Март 24, 2014, 17:02
А у меня как?

Я передаю индекс текущего элемента модели, в который я хочу добавить элемент

Вот я и не пойму.


Название: Re: Model-View
Отправлено: demaker от Март 24, 2014, 17:09
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент
Значит он и парент, разве нет?


Название: Re: Model-View
Отправлено: Old от Март 24, 2014, 17:12
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент
Значит он и парент, разве нет?
Да, но тогда значение row вычисляется неправильно.


Название: Re: Model-View
Отправлено: demaker от Март 25, 2014, 09:48
Я передаю индекс текущего элемента модели, в который я хочу добавить элемент
Значит он и парент, разве нет?
Да, но тогда значение row вычисляется неправильно.


Код
C++ (Qt)
void TreeModelBrowser::updateModelInsertRow(QModelIndex index)
{
   if(index.isValid())
   {
       CommonElement *ce = reinterpret_cast<CommonElement*>(index.internalPointer());
       int row = ce->children().length();
       beginInsertRows(index,row,row);
       ce->appendChild();
       endInsertRows();
   }
}
 

Так надо???


Название: Re: Model-View
Отправлено: Old от Март 25, 2014, 10:20
Да. Так новый элемент добавиться в конец ветки.


Название: Re: Model-View
Отправлено: demaker от Март 25, 2014, 10:21
Да. Так новый элемент добавиться в конец ветки.

Нет к сожалению.
Так же через раз


Название: Re: Model-View
Отправлено: Old от Март 25, 2014, 16:33
Нет к сожалению.
Так же через раз
Скажите, а в консоль какие нибудь предупреждения сыпятся?

Попробуйте на простой модели это отработать. Если не получиться, выкладывайте демонстрашку сюда, будем пробовать вместе. :)