Код: Выделить всё
class MoveItemTreeView(QTreeView):
def moveItem(self, source_row: int, destination_row: int) -> None:
"""Move an item in the tree widget from source to destination."""
model = typing.cast(QStandardItemModel, self.model())
columns = model.takeRow(source_row)
model.insertRow(destination_row, columns)
Это работает правильно и обеспечивает желаемое поведение. Моя проблема в том, что эта операция кажется чтобы удалить любые виджеты, связанные с этим индексом, с помощью setIndexWidget, виджеты просто исчезнут.
Я предоставлю изображение, демонстрирующее поведение:

Это минимальный воспроизводимый пример, сгенерировавший это изображение:
< pre class="lang-py Prettyprint-override">
Код: Выделить всё
import sys
import typing
from PySide6.QtGui import QStandardItem, QStandardItemModel
from PySide6.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QTreeView,
QVBoxLayout,
QWidget,
)
class MoveItemTreeView(QTreeView):
def moveItem(self, source_row: int, destination_row: int) -> None:
"""Move an item in the tree widget from source to destination."""
model = typing.cast(QStandardItemModel, self.model())
columns = model.takeRow(source_row)
model.insertRow(destination_row, columns)
class MainWindow(QMainWindow):
def __init__(self) -> None:
super().__init__()
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
tree_view = MoveItemTreeView()
layout.addWidget(tree_view)
model = QStandardItemModel()
tree_view.setModel(model)
# Add some items
for i in range(5):
item = QStandardItem(f"Item {i}")
model.appendRow(item)
for j in range(3):
child = QStandardItem()
item.appendRow(child)
tree_view.setIndexWidget(child.index(), QLabel(f"Child {j}"))
tree_view.moveItem(2, 3)
tree_view.expandAll()
self.setGeometry(100, 100, 600, 600)
class App(QApplication):
def __init__(self) -> None:
super().__init__()
self.window = MainWindow()
self.window.show()
if __name__ == "__main__":
app = App()
sys.exit(app.exec())
Я попробовал вручную повторно связать виджеты в moveItem, собрать их перед перемещением и использовать setIndexWidget после него, но это приводило только к зависаниям и сбоям.
Поэтому мой вопрос таков: Я делаю что-то неправильно, это неопределенное или недокументированное поведение, или я столкнуться с ошибка?
Я знаю, что могу просто перегенерировать виджеты, мне просто интересно, что именно происходит не так, потому что я ничего не нашел об этом поведении в документации.
Изменить:
Я знаю, что использование setIndexWidget обычно не подходит, и специальный QStyledItemDelegate предпочтительнее, в моем случае я использовать пользовательские виджеты, которые действуют как редакторы - задача, для которой делегат был бы идеален, проблема заключалась в том, что делегат на самом деле не предлагал хороший способ «всегда показывать» редактор, а вместо этого зависел от триггеров редактора представления. Я пытался заставить это работать, но простое использование виджета оказалось гораздо более простым (и, на мой взгляд, более аккуратным) решением, тем более что оно просто работает.
Подробнее здесь: https://stackoverflow.com/questions/793 ... et-in-view
Мобильная версия