Как использовать QAbstractItemModel?

Мне нужно использовать QAbstractItemModel с QTreeView в PyQt.

В методе dropMimeData я хочу удалить исходную строку (если это определенный MIME_TYPE). Как мне получить строку и parentIndex источника? Или мне нужно сделать это каким-то другим способом.

def dropMimeData(self, mimedata, action, row, column, parentIndex):


person hosscomp    schedule 20.04.2012    source источник
comment
Вы решили, что QTreeWidget будет недостаточно? Как насчет QTreeView + QStandardItemModel? Что вам нужно, что требует от вас подкласса и создания собственной пользовательской модели?   -  person jdi    schedule 21.04.2012
comment
@Tim: Я думаю, что ваше редактирование, хотя да, оно указывает на ясность вопроса, значительно меняет то, что может спрашивать ОП. Возможно, для вас было бы лучше оставить комментарий и позволить ОП скорректировать этот беспорядок. Меня больше интересовало, почему ему нужна абстрактная модель, а не его вопрос о dropMimeData, который, как я полагаю, может быть на самом деле неуместным.   -  person jdi    schedule 21.04.2012
comment
@jdi Я ничего не определил. Я начал с самой близкой вещи, которую я мог найти, которая казалась близкой к тому, что мне нужно. Мне нужно одно дерево исходных элементов (пока один столбец имен) и другое дерево, на которое я хочу поместить эти элементы. В целевом дереве мне нужно переместить элементы в другое место. Я предполагаю, что это будет внутреннее перетаскивание, а затем удаление исходного элемента. Я использовал модели с подклассами только для того, чтобы определить, из какого дерева были взяты элементы, чтобы не удалять их из исходного дерева.   -  person hosscomp    schedule 23.04.2012
comment
@jdi Я не смог найти режим DragDropMode, который действовал бы как internalMove, а также допускал удаление из другого представления. Должен быть более простой способ сделать это, и я был бы благодарен узнать его. Кто-то еще предложил использовать подклассы.   -  person hosscomp    schedule 23.04.2012
comment
QAbstractItemModel предназначен для тех случаев, когда вам нужен пользовательский тип модели, но просто для перетаскивания это не обязательно. Вам придется реализовать больше, чем вам нужно. QStandardItemModel должен быть полностью функциональным и готовым к использованию с QTreeView. Вы просто подклассируете один из них, а затем повторно реализуете методы dragEvent/dropEvent. Если вы хотите сохранить две совершенно отдельные модели, то выбросьте весь этот беспорядок и просто создайте подкласс QTreeWidget, у которого есть встроенная модель.   -  person jdi    schedule 23.04.2012


Ответы (1)


Мои комментарии были слишком длинными, поэтому я решил начать ответ с информации сейчас.

QAbstractItemModel — это базовый класс, который нужен, когда вам нужен индивидуальный способ моделирования ваших данных, который не соответствует ни одному из существующих, например, где взять данные и как представить их в виде элементов. Он не готов к использованию «из коробки», так как требует реализации ряда методов. Вам, вероятно, не следует начинать с этого класса, если у вас нет веских причин для этого, так как для его запуска и работы требуется гораздо больше работы.

Для простого перетаскивания и использования основных элементов QStandardItemModel должен быть готов к использованию. Вы просто создаете QStandardItems и заполняете модель. Для перетаскивания вы должны создать подкласс модели и просто реализовать соответствующие методы drag*Event и drop*Event в соответствии с вашими потребностями.

Использование QStandardItemModel + QTreeView позволяет вам иметь несколько представлений, использующих одну и ту же модель и одновременно визуализирующих ее по-разному. Но учитывая, что вы сказали, что хотите сохранить два разных набора независимых данных, и что вы новичок в Qt, я настоятельно рекомендую вам просто использовать два QTreeWidget. QTreeWidget — это комплексный пакет представления и модели. Это будет намного проще для вас использовать сейчас.

Используя QTreeWidget, вы создадите их подклассы и реализуете необходимые события перетаскивания точно так же, как и для QTreeView, но вам больше не нужно беспокоиться о моделях по отдельности.

Вот ссылка на сообщение о перетаскивании с помощью QTreeWidget: http://www.qtcentre.org/threads/5910-QTreeWidget-Drag-and-drop
В них упоминаются рекомендуемые методы для реализации, а также то, что вы должны делать с подклассом QTreeWidgetItem для определения mimeData.

person jdi    schedule 23.04.2012
comment
Вы всегда можете переопределить QWidget::mousePressEvent(QMouseEvent*) и создать свой собственный объект QDrag, указав тип перетаскивания (переместить или скопировать) вручную. Это похоже на одну из вещей, которые мне нужно было знать. Мой первоначальный вопрос заключался в том, где я могу получить общее представление об этих классах и о том, как их использовать. Для PyQt, похоже, единственное место — это ссылки на классы и онлайн-примеры (в основном на C++) и множество вопросов. Кажется, у меня никогда не было проблем с поиском хороших книг и руководств по Java. Спасибо за вашу помощь. - person hosscomp; 24.04.2012
comment
@hosscomp: документы для C++ API почти такие же для python, за исключением синтаксиса. Хорошая книга: qtrac.eu/pyqtbook.html. Достаточно просто прочитать документацию по C++, которой довольно много. У них есть целый раздел о перетаскивании - person jdi; 24.04.2012
comment
Спасибо. Думаю, эта книга будет мне очень полезна. Только сегодня я обнаружил, как добавить обработчик dragEnterEvent в TreeView и проверить, является ли event.source() self. - person hosscomp; 27.04.2012
comment
Я читал книгу и добавил обработчик dragMoveEvent в свой подкласс QTreeView, который устанавливает действие перетаскивания в Qt.MoveAction, если источник является self. Он по-прежнему делал ход вместо копии и по-прежнему проходил через dropMineData. Но затем я запустил его в Spider (вместо Eclipse), и он работает так, как я хотел. Это также работало из IDLE и командной строки. Я не могу понять разницу. - person hosscomp; 07.05.2012
comment
@hosscomp: у него было другое поведение, просто когда он запускался в другой среде IDE? Я только предполагаю, что это может быть связано со ссылкой на разные интерпретаторы или разные версии Qt? Я обычно просто запускаю свой из командной строки. Это верный тест, чтобы узнать, действительно ли он работает правильно. - person jdi; 07.05.2012
comment
Это полезно знать, потому что мне нравится использовать Eclipse. Я не могу найти другую ссылку, хотя. - person hosscomp; 08.05.2012