Название: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 20, 2019, 17:38 Не в первый раз звучит вопрос :)
Значит, так и не решённый прежде. Уберегите от флуда, но про иерархические заголовки решения не нашёл. Опирался на сообщения аж 2008 года. http://www.prog.org.ru/topic_6637_15.html Написал всё в рамках изложенной стратегии Zmeishe. Всё работает, но есть нюансы. У меня условия - QT 4.8.0. Не претендую на авторские права. Готов выложить свой код, поскольку появились вопросы. Если есть кто живой в этой теме, то помогите неопытному. Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 13:48 И так, всё по порядку.
Это .pro - файл Код: QT += core это testTable.ui Код: <?xml version="1.0" encoding="UTF-8"?> Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 13:50 Содержимое main.cpp
Код: #include "testTable.h" Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 13:51 Содержимое testTable.h
Код: #ifndef TEST_TABLE_H_21_08_2019_11_49 Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 13:52 Содержимое testTable.cpp
Код: #include "testTable.h" Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 13:54 Реализую стратегию выше упомянутого Zmeishe, за что ему очень благодарен.
Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 14:02 Наблюдаем результат
(http://) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 14:05 Получается, что QTableWidget не видит вложенные столбцы,
а значит мне их нужно добавлять вручную? Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 14:07 У меня есть код с ручным добавлением и я его выложу,
но может это уже "костыль"? Что я на данном этапе не так делаю? Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 16:05 Изменяю код
Код: CDataHeaderView::CDataHeaderView(QWidget* pParent): Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 16:07 Модифицирую код отрисовки
Код: void CDataHeaderView::paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 16:09 Наблюдаем результат
(http://) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 16:12 И всё бы хорошо, но стоит провести курсор над заголовком - начинаются неприятности.
Понятно, что я не рисую "костыльный" заголовок, но попытка его отрисовать - тоже не спасает. Помогите форумчане ;) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 16:13 Подожду ответа :)
Название: Re: QTableWidget иерархические заголовки Отправлено: ViTech от Август 21, 2019, 16:50 Лучше упакуйте все необходимые файлы проекта в архив и "вложите" в сообщение, тогда может кто-нибудь и посмотрит его.
Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 21, 2019, 17:00 Спасибо за совет :) Я же новичок:)
В архиве последняя версия. Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 11:23 Чёт я сам с собою :)
Иногда полезно просто высказаться. paintSection константная функция и вызвать из нее слот для обновления соседней секции ну никак не удавалось. Написал в своем классе константный сигнал и законнектил на неконстантный слот. Всё заработало. Новый код paintSection Код: void CDataHeaderView::paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 11:27 Сознательно не усложняю код для обработки иерархии.
Хочу на простом примере разобраться. Сейчас ну никак не рисуются два нижних подзаголовка, хотя отладчик туда попадает. И геометрия правильная. (http://) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 12:20 Ну что, благодаря форуму вопрос решил :)
Последняя ошибка связана была с тем, что QStandardItem::takeRow(...) не только возвращает столбцы строки, но и удаляет их. Перешел на функцию child(...) и всё заработало. Название: Re: QTableWidget иерархические заголовки Отправлено: ViTech от Август 22, 2019, 12:43 Ну что, благодаря форуму вопрос решил :) Это хорошо. На форум надейся, а сам не плошай :). Название: Re: QTableWidget иерархические заголовки Отправлено: Dimas от Август 22, 2019, 13:14 Для истории прикрепите пожалуйста итоговую версию
Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 14:34 Ещё раз выражаю огромную благодарность
Zmeishe http://www.prog.org.ru/topic_6637_15.html Ответ #25 : Апрель 05, 2008, 08:40 Не нашёл способа на форуме сделать это лично, да и времени прошло... Надеюсь он вырос в нашей среде. И дай Бог ему здоровья. Подведу небольшие итоги. Итак, QHeaderItemView не подхватывает от QStandardItemModel вложенные заголовки, поэтому лишние столбцы нужно добавлять вручную. Переопределяемая QHeaderItemView::paintSection(...) const не позволяет внутри себя вызывать слоты базового класса для перерисовки объединенных ячеек. Для реализации необходимого был введен константный сигнал signals: void drawSection(int Idx) const; который я связал с нужным слотом connect(this,SIGNAL(drawSection(int)),this,SLOT(updateSection(int))); Работает. Хотя, намеренно последовательно излагал свои шаги, чтобы уберечься от "костылей" :) Последние штрихи связаны с текущим уровнем новичка, который на Ваших глазах подрос :) Новичок мотивирован на получение знаний и летает с удовольствием на c++ и Qt :) Прилагаю финальный архив. Сейчас занимаюсь абстрагированием изученного кода, чтобы реализовать многоуровневую вложенность заголовков. Как писал стратег Zmeishe(с) " Далее создаём функцию QVariant headerData(int Section, Qt::Orientation orientation, int nRole) const; Вообще это функция Модели её там надо было перекрывать, но я сделал здесь, т.к. уже написал, что не принял оконч. решения где им быть. Для работы headerData понадобятся две рекурсивные функции, которые по int Section будут возвращать номер начальной секции группы (ветки) в которую входит Section и номер конечной секции группы. " Некоторое время, пока код не начал обрастать корпоративными особенностями, готов им делиться :) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 14:49 Закралась мысль ;)
Будь я поближе к разработчикам Qt, то научил бы QHeaderView правильно разгребать модель, дабы не устраивать пляски вокруг известной темы иерархических заголовков :) Название: Re: QTableWidget иерархические заголовки Отправлено: ViTech от Август 22, 2019, 14:58 Будь я поближе к разработчикам Qt, то научил бы QHeaderView правильно разгребать модель, дабы не устраивать пляски вокруг известной темы иерархических заголовков :) Тогда становитесь ближе, вносите свой вклад: Contribute to Qt (https://www.qt.io/contribute-to-qt) :). Название: Re: QTableWidget иерархические заголовки Отправлено: ViTech от Август 22, 2019, 15:28 Вот подходящий тикет: Use span data from QAbstractItemModel in QTableView. (https://bugreports.qt.io/browse/QTBUG-6508) Ему всего 10 лет :).
Хотя нет, это не про заголовки. Название: Re: QTableWidget иерархические заголовки Отправлено: Авварон от Август 22, 2019, 15:53 Хотя нет, это не про заголовки. Я начал писать долгий текст с тем же посылом, но потом бросил, ибо... Если мы хотим иерархические заголовки с несколькими рядами/колонками и спанами то мы придем к тому, что такому заголовку надо устанавливать отдельную _модель_ которая будет отдавать данные для хедера через rowCount/columnCount/index/data а не через headerData. Иначе придется тупо продубрировать весь API еще и для хедера (headerRowCount/headerColumnCount/headerIndex (мы же хотим деревья)/headerData/headerSpan). Кажется, такой подход слишком сложный (особенно если учесть что в горизонтальном хедере должно быть headerRowCount рядов но columnCount (без header) колонок, чтобы колонки/ряды совпадали с теми, что в основной таблице. а в вертикальном - всё наоборот). А еще надо теперь не запутаться где headerIndex а где обычный и не перепутать их случайно. Так что да, это таки применимо, но как указано выше - для кастомной view, которая игнорит headerData и берет данные из отдельной полноценной модели. Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 16:56 Абстрагировался немного. Теперь дополнительные столбцы мечу индексами в подзаголовках.
Шалю с третьим столбцом. Архив и результат на экране выкладываю. В результате смущает игра с толщиной текста в сложных заголовках. Понятно, что от лишней перерисовки ??? не зря же слот так просто не вызывался. Руки чешутся - теперь абстрактно пойду на третий этаж заголовка :) Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 22, 2019, 17:34 Мне бы в данный момент (для лазания по этажам) пригодился QStandatrdItem::parent(),
но он в нуле, казалось бы у дочерних элементов (подстолбцов). Попробовал для их добавления использовать setChild(...) вместо appendRow(...) эффект тот же. Ни в конструкторах ничего про parent, ни в методах... Может подскажет кто как проинициализировать parent в дочерних элементах QStandatrdItem ??? Понятно, что от безысходности можно вопрос решить усложнением QStandardItem::data, но не хотелось бы :) Название: Re: QTableWidget иерархические заголовки Отправлено: ViTech от Август 22, 2019, 18:25 Если хотите нестандартного поведения от таблицы, лучше пользуйтесь QAbstractItemModel и QTableView/QAbstractItemView. Их можно гибче настроить под свои хотелки, чем готовые модели/виды переделывать.
Название: Re: QTableWidget иерархические заголовки Отправлено: Иваныч от Август 30, 2019, 17:42 Спасибо за участие :). Воспользовался Вашим советом, но в итоге (по моему разумению) всё равно всё сводится к
эффективному переопределению QHeaderView::paintSection(...) const. Повозился, нашёл, что некорректно работает QHeaderView::sectionPosition(...) при сдвиге ScrollBar-а. Для всех секций, слева за окном возвращает 0. Справился через перебор QHeaderView::sectionWidth(...). Разделил операции наполнения "дерева" сложных колонок и формирования дополнительных колонок. Рекурсия рулит на разборе строки с колонками и их отрисовке. Для отладки внедрил над таблицей счетчик отрисовок секций. Жалко, что никто особо не поддержал тему :(. Честь имею. Результаты прилагаю. |