Много вопросов про модель\представление |
Здравствуйте, гость ( Вход | Регистрация )
Много вопросов про модель\представление |
Xantrax |
25.11.2013, 0:45
Сообщение
#1
|
Новичок Группа: Неактивирован Сообщений: 8 Регистрация: 14.10.2012 Пользователь №: 3561 Спасибо сказали: 0 раз(а) Репутация: 0 |
Здравствуйте, есть ряд вопросов по архитектуре модель\представление.
Читаю http://qtdocs.narod.ru/, раздел создание новых моделей... Источник данных у нас QStringList, значит можно унаследоваться от QAbstractListModel, что и делается в объяснении... Наследуюсь:
Определяя конструктор сталкиваюсь с проблемой, что не могу инициализировать приватную переменную QStringList stringList
no match for call to '(QStringList) (QStringList&)' а вот таким образом могу:
Хорошо, далее.... Написано, что "Кроме конструктора модели, мы должны реализовать только две функции: rowCount(), data()". Зачем, если я могу ни разу эти функции не вызвать? Далее они переопределяют виртуальный метод rowCount(), ну и я собственно у себя этот метод в классе епреопределяю:
Вот только зачем туда подавать QModelIndex &parent, если мы его нигде не спользуем? Хорошо, допустим далее, я хочу посмотреть что у меня получилось, беру свою модель, беру представление (QListView) и отображаю все это на виджете...
Допустим я не зря переопределил виртуальный метод класса QAbstractListModel rowCount(const QModelIndex &parent), как теперь мне узнать количество строк в моей модели?
Метод требует QModelIndex &parent, что туда подать? ?Далее, нам в руководстве предлагается переопределить еще один виртуальный метод data();
И тут у меня ступор, если index не валидный(первое if()), то что возвращается? Аналогично, что возвращается, если срабатывает второй if()? Рандомное число? А может лучше вернуть что-нить такое, чтобы понять что идекс не валидный, или индекс вернулся больше количества срок в stringList? В общем, как-то все жутко на первых порах... |
|
|
ilyabvt |
25.11.2013, 16:45
Сообщение
#2
|
Активный участник Группа: Участник Сообщений: 297 Регистрация: 23.6.2011 Пользователь №: 2765 Спасибо сказали: 45 раз(а) Репутация: 3 |
Цитата Читаю http://qtdocs.narod.ru/ Читать документацию к версии 4.1, когда уже вышла 5.1, не совсем разумно. Неужели из-за того что оригинальная документация на английском? Цитата no match for call to '(QStringList) (QStringList&)' Потому что у QStringList нет конструктора принимающего QStringList по ссылке, только по const ссылке. У себя в конструкторе используйте константную ссылку. Цитата Написано, что "Кроме конструктора модели, мы должны реализовать только две функции: rowCount(), data()". Зачем, если я могу ни разу эти функции не вызвать? Базовый класс может. Цитата Далее они переопределяют виртуальный метод rowCount(), ну и я собственно у себя этот метод в классе епреопределяю:
Вот только зачем туда подавать QModelIndex &parent, если мы его нигде не спользуем? Это просто пример простейшего rowCount. Цитата Метод требует QModelIndex &parent, что туда подать? Вот пример на 3 строки: http://qt-project.org/doc/qt-5.1/qtwidgets...g-model-indexes Цитата И тут у меня ступор, если index не валидный(первое if()), то что возвращается? Аналогично, что возвращается, если срабатывает второй if()? Возвращается заведомо некорректный QVariant. Цитата А может лучше вернуть что-нить такое, чтобы понять что идекс не валидный, или индекс вернулся больше количества срок в stringList? Вы как раз и возвращаете ответ который дает понять что индекс не валидный. |
|
|
Анна |
25.11.2013, 16:48
Сообщение
#3
|
Активный участник Группа: Участник Сообщений: 276 Регистрация: 22.5.2008 Из: Зеленоград Пользователь №: 181 Спасибо сказали: 30 раз(а) Репутация: 4 |
no match for call to '(QStringList) (QStringList&)' Наверное, потому что в определениии конструктора написано так QStringList ( const QString & str ). -> const <- попробуй добавить в аргумент конструктора. Написано, что "Кроме конструктора модели, мы должны реализовать только две функции: rowCount(), data()". Зачем, если я могу ни разу эти функции не вызвать? Ты, может, и не вызовешь их, зато сама модель ими пользуется, вьювер ими пользуется.Вот только зачем туда подавать QModelIndex &parent, если мы его нигде не спользуем? Потому, что эта функция так определена в родительском классе: int QAbstractItemModel::rowCount ( const QModelIndex & parent = QModelIndex() ) const [pure virtual] Обрати внимание на [pure virtual] . Это тоже ответ на твой вопрос "Зачем, если я не буду вызывать?" и это означает, что ,если ты не переопределишь эту функцию, то твой класс останется виртуальным, и компелятор тебя обругает. Метод требует QModelIndex &parent, что туда подать? Если ты внимательно посмотришь на определение rowCount, то увидишь, что за тебя уже всё сделали - const QModelIndex & parent = QModelIndex() - тебе и аргумент определили и по умолчанию в него подставили QModelIndex(),и тебе уже ничего не надо указывать в качестве аргумента. И тут у меня ступор, если index не валидный(первое if()), то что возвращается? Возвращается пустышка. Вьювер знает, что делать с QVariant() - он тебе ничего не отобразит (ну, нечего отбражать!). Рандомное число? А может лучше вернуть что-нить такое, чтобы понять что идекс не валидный, или индекс вернулся больше количества срок в stringList? В общем, как-то все жутко на первых порах... Так ведь QVariant() и означает "ничего" - У меня нет ничего, что можно было бы отобразить для этого индекса (потому что он невалидный - например, он содержит координаты -1, -1 ), у меня нет ничего для индекса, который вылетел за пределы моего списка, я могу предложить тебе для данного индекса только то, что можно отобразить на экране (это третий if). Не забывай, что всё завязано на QAbstractItemModel - классе, который сделан как можно более универсалей. Авторы не могут предугадать, что именно тебе захочестя видеть в качестве данных в твоём списке - строки, инты, ёлочные игрушки или другие подарки, поэтому тебе сделали универсальную коробочку и работают с коробоской, а уж что ты туда положишь, это уже твоя забота, а не их, хоть слона положи. В QVariant это универсальная обёртка для почти любых данных, туда можно положить, всё что угодно (до некоторой степени, конечно), И большинство классов умеют и будут работать с этой обёрткой. QVariant() означает "ничего" - У меня нет ничего, что можно было бы отобразить для этого индекса, у меня нет ничего для индекса, который вылетел за пределы моего списка, я могу предложить тебе для данного индекса только то, что можно отобразить на экране (это третий if). В общем, почитай обзорные статьи в аасистенте про Модель/Представление, ты многое поймёшь. ilyabvt, ! |
|
|
Steklova Olga |
25.11.2013, 17:26
Сообщение
#4
|
Участник Группа: Участник Сообщений: 198 Регистрация: 27.9.2011 Из: Санкт-Петербург Пользователь №: 2912 Спасибо сказали: 5 раз(а) Репутация: 4 |
Привет!
no match for call to '(QStringList) (QStringList&)' такая ошибка может возникнуть, если описав класс так mystringlistmodel.h
mystringlistmodel.cpp
надо так: mystringlistmodel.h
mystringlistmodel.cpp
обрати внимание: explicit MyStringListModel(const QStringList &strings, QObject *parent = 0) : QAbstractListModel(parent), stringList(strings) {} т.е. имя_класса(список_параметров) : (список_инициализаторов_компонентов_данных) {тело_конструктора} в данном случае переменная stringList инициализируется прямо здесь, тело конструктора пустое. |
|
|
Xantrax |
25.11.2013, 18:25
Сообщение
#5
|
Новичок Группа: Неактивирован Сообщений: 8 Регистрация: 14.10.2012 Пользователь №: 3561 Спасибо сказали: 0 раз(а) Репутация: 0 |
обрати внимание: explicit MyStringListModel(const QStringList &strings, QObject *parent = 0) : QAbstractListModel(parent), stringList(strings) {} т.е. имя_класса(список_параметров) : (список_инициализаторов_компонентов_данных) {тело_конструктора} в данном случае переменная stringList инициализируется прямо здесь, тело конструктора пустое. Всегда считал, что обе записи имеют право быть. Т.е. можно инициализировать переменные либо в заголовке конструктора, либо в самом конструкторе, не вижу тут ничего криминального. |
|
|
ilyabvt |
25.11.2013, 19:19
Сообщение
#6
|
Активный участник Группа: Участник Сообщений: 297 Регистрация: 23.6.2011 Пользователь №: 2765 Спасибо сказали: 45 раз(а) Репутация: 3 |
Цитата Всегда считал, что обе записи имеют право быть. Т.е. можно инициализировать переменные либо в заголовке конструктора, либо в самом конструкторе, не вижу тут ничего криминального. Я вижу. Конструктор должен выполнятся до первого обращения к переменной. Поэтому и придумали список инициализации. Если разрешить обращение к конструктору в теле другого конструктора, то нет гарантий что вызываемый конструктор выполнится до обращения к переменной. Сообщение отредактировал ilyabvt - 25.11.2013, 19:19 |
|
|
Xantrax |
25.11.2013, 23:01
Сообщение
#7
|
Новичок Группа: Неактивирован Сообщений: 8 Регистрация: 14.10.2012 Пользователь №: 3561 Спасибо сказали: 0 раз(а) Репутация: 0 |
[/quote]
то нет гарантий что вызываемый конструктор выполнится до обращения к переменной. [/quote] Если честно, я все равно не понял, ну не выполнится он до обращения к переменной, значит выполнится после... Конструктор всегда выполняется при создании объекта класса.. Цитата то нет гарантий что вызываемый конструктор выполнится до обращения к переменной. Если честно, я все равно не понял, ну не выполнится он до обращения к переменной, значит выполнится после... Конструктор всегда выполняется при создании объекта класса.. int QModelIndex::row () const Returns the row this model index refers to. Перевожу: врзвращает строку на которую ссылается индекс модели. А на самом деле оказывается - возвращается номер строки... |
|
|
Анна |
26.11.2013, 9:29
Сообщение
#8
|
Активный участник Группа: Участник Сообщений: 276 Регистрация: 22.5.2008 Из: Зеленоград Пользователь №: 181 Спасибо сказали: 30 раз(а) Репутация: 4 |
Перевожу: врзвращает строку на которую ссылается индекс модели. А на самом деле оказывается - возвращается номер строки... Не надо особо сильно придираться к тексту, это ведь не англичане пишут. Даже больше скажу, спустя какое-то время стала различать стили авторов разных кусков документации - там есть один, кто в английском вообще не рубит, как только пишет сложно-подчинённое предложение, так вся грамматика накрывается медным тазом, и остаётся только догадываться (или проверять на опыте), что же автор имел ввиду. По int и так понятно, что возвращается не данные всей строки. Под row во всём, что касается модели и представление, подразумевается номер строки, а под column - номер колонки. Всегда считал, что обе записи имеют право быть. Т.е. можно инициализировать переменные либо в заголовке конструктора, либо в самом конструкторе, не вижу тут ничего криминального. В том-то и дело, что вызывая stringList(strings), ты не производишь инициализацию, а пытаешься вызвать конструктор с инициализацией. Когда ты попал в тело конструктора модели, у тебя уже отработал конструктор QStringList() для переменной stringList , а ты вызваешь конструкторещё раз - даже не знаю, что получится, видимо, потому и ругается, что не может пересоздать уже созданное.Хочется тебе проинициализировать список в теле, пожалуйста, есть много способов, но конструктор-то ещё раз зачем вызывать? На худой конец, возможет такой вариант: { stringList = QStringList(strings); } Конечно, если для этого класса реализован оператор =. Но это какой-то совсем по-детски, и опять же, обрати внимание, что даже тут сперва отработал конструктор по умолчанию для stringList , а в теле выполнятся следующие действия: создастся список, который тут же при создании проинициализируется переменной strings, данные из этого списка копируются в stringList, созданный по QStringList(strings) уничтожится при выходе из тела. Сообщение отредактировал Анна - 26.11.2013, 10:10 |
|
|
Xantrax |
26.11.2013, 12:02
Сообщение
#9
|
Новичок Группа: Неактивирован Сообщений: 8 Регистрация: 14.10.2012 Пользователь №: 3561 Спасибо сказали: 0 раз(а) Репутация: 0 |
Не надо особо сильно придираться к тексту, это ведь не англичане пишут. В том-то и дело, что вызывая stringList(strings), ты не производишь инициализацию, а пытаешься вызвать конструктор с инициализацией. Когда ты попал в тело конструктора модели, у тебя уже отработал конструктор QStringList() для переменной stringList , а ты вызваешь конструкторещё раз - даже не знаю, что получится, видимо, потому и ругается, что не может пересоздать уже созданное. Спасибо, доходчиво. |
|
|
Litkevich Yuriy |
26.11.2013, 13:59
Сообщение
#10
|
разработчик РЭА Группа: Сомодератор Сообщений: 9669 Регистрация: 9.1.2008 Из: Тюмень Пользователь №: 64 Спасибо сказали: 807 раз(а) Репутация: 94 |
Читаю http://qtdocs.narod.ru/, раздел создание новых моделей... Эта дока уже заброшена, её немалая часть (спасибо автору перевода) перекочевала сюда |
|
|
Текстовая версия | Сейчас: 24.4.2024, 2:04 |