Как визуализировать сложный виджет внутри элемента дерева в QT? - PullRequest
9 голосов
/ 26 января 2010

У меня следующая проблема с каркасом модель / представление QT. Я хочу визуализировать виджет внутри элемента представления таблицы.

Сначала я подумал об использовании

void QAbstractItemView::setIndexWidget( const QModelIndex & index, QWidget * widget )

Но документация для этой функции прямо гласит:

Эта функция должна использоваться только для отображать статический контент в пределах видимая область, соответствующая предмету данных. Если вы хотите отобразить пользовательские динамический контент или реализовать пользовательский виджет редактора, подкласс QItemDelegate вместо этого.

Поэтому они предлагают использовать делегатов здесь. Ну, пока все хорошо. Я знаю, что делегаты могут быть использованы для создания редактора, которым может быть любой виджет QT. Но здесь есть проблема - я не хочу, чтобы этот виджет был редактором - я хочу отображать элемент с этим виджетом всегда. И не просто «рендер», мне нужно, чтобы он точно описывал поведение виджета.

Теперь виджет, который я хочу использовать - это пользовательский виджет, который является контейнером некоторых других виджетов (несколько флажков, несколько кнопок с некоторым макетом).

Решение, которое я рассматриваю, выглядит следующим образом:

  1. Перенесите внешний вид моего пользовательского виджета в растровое изображение.
  2. Позвольте делегату нарисовать себя, используя это растровое изображение.
  3. Когда мышь находится над элементом, вид автоматически начинает редактирование (я не
    знаю, как это сделать, но я полагаю, это возможно)
  4. Пусть делегат создаст мой виджет в качестве редактора для элемента.

Кажется, это решение работает, но пахнет плохо для меня. Может кто-нибудь что-нибудь о более элегантном решении этой проблемы?

Спасибо.

Ответы [ 2 ]

7 голосов
/ 26 января 2010

Делегаты отвечают за создание редакторов , а также за все необходимое отображение. Они могут использовать стили для выполнения большей части рисования, например рисовать индикатор выполнения или рисовать вручную.

Однако делегат не является виджетом. Если редактор не был вызван, у него нет доступа к большинству вещей, которые мог бы иметь виджет. Они очень разные, имеют разные цели и выполняют разные задачи.

Один из наиболее неприятных аспектов для делегатов заключается в том, что они статичны . Если что-то в модели не инициирует обновление (или виджет не настроен для просмотра событий при наведении), делегат не будет использоваться для перерисовки любых данных - буферизованное представление будет отображаться на экране.

У вас есть некоторый контроль над тем, когда редактор вызывается с помощью триггеров редактирования , хотя вы можете определенно справиться с этим с помощью некоторого пользовательского кода, например, путем отслеживания мыши.

0 голосов
/ 22 октября 2018

Вы можете позвонить QAbstractItemView.openPersistentEditor(index) для каждой ячейки, для которой вам нужен постоянный сложный виджет. Два ключа, чтобы сделать эту работу:

  1. QStyledItemDelegate.sizeHintChanged.emit(index) необходимо вызывать каждый раз, когда изменяется размер виджета редактора.
  2. Реализация QStyledItemDelegate.sizeHint() может быть хитрой и утомительной (или вы можете сделать index.internalPointer().editor_widget.sizeHint(), если вы сохранили ссылку редактора на внутренний указатель во время QStyledItemDelegate.createEditor()

Недавно я использовал метод openPersistentEditor для отображения таблиц в древовидных представлениях, однако следует отметить, что открытие редакторов обходится дорого, поэтому, если у вас есть тысячи индексов, и все они загружаются одновременно, это может занять некоторое время. Есть много способов решить эту проблему:

  1. Загрузка модели постепенно с использованием потока
  2. Используйте механизм Qt's fetchMore()
  3. вызов openPersistentEditor пошагово (с использованием таймера или по мере их появления в первый раз)
  4. вызовите openPersistentEditor, когда родительский узел раскрыт, и closePersistentEditor, когда родительский узел свернут, и, возможно, ограничьте использование расширения для всех узлов со многими дочерними элементами.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...