Russian Qt Forum
Май 07, 2024, 02:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2
1  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 30, 2019, 17:42
Спасибо за участие Улыбающийся. Воспользовался Вашим советом, но в итоге (по моему разумению) всё равно всё сводится к
эффективному переопределению QHeaderView::paintSection(...) const.
Повозился, нашёл, что некорректно работает QHeaderView::sectionPosition(...) при сдвиге ScrollBar-а. Для всех
секций, слева за окном возвращает 0. Справился через перебор QHeaderView::sectionWidth(...).
Разделил операции наполнения "дерева" сложных колонок и формирования дополнительных колонок.
Рекурсия рулит на разборе строки с колонками и их отрисовке.
Для отладки внедрил над таблицей счетчик отрисовок секций.
Жалко, что никто особо не поддержал тему Грустный.
Честь имею.
Результаты прилагаю.
2  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 17:34
Мне бы в данный момент (для лазания по этажам) пригодился QStandatrdItem::parent(),
но он в нуле, казалось бы у дочерних элементов (подстолбцов). Попробовал для их
добавления использовать setChild(...) вместо appendRow(...) эффект тот же.
Ни в конструкторах ничего про parent, ни в методах...

Может подскажет кто как проинициализировать parent в дочерних элементах QStandatrdItem Непонимающий

Понятно, что от безысходности можно вопрос решить усложнением QStandardItem::data,
но не хотелось бы Улыбающийся
3  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 16:56
Абстрагировался немного. Теперь дополнительные столбцы мечу индексами в подзаголовках.
Шалю с третьим столбцом.
Архив и результат на экране выкладываю.
В результате смущает игра с толщиной текста в сложных заголовках.
Понятно, что от лишней перерисовки Непонимающий не зря же слот так просто не вызывался.
Руки чешутся - теперь абстрактно пойду на третий этаж заголовка Улыбающийся
4  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 14:49
Закралась мысль Подмигивающий
Будь я поближе к разработчикам Qt, то научил бы QHeaderView правильно разгребать модель,
дабы не устраивать пляски вокруг известной темы иерархических заголовков Улыбающийся
5  Qt / Вопросы новичков / 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 и номер конечной секции группы.
"

Некоторое время, пока код не начал обрастать корпоративными особенностями, готов им делиться Улыбающийся
6  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 12:20
Ну что, благодаря форуму вопрос решил Улыбающийся
Последняя ошибка связана была с тем, что QStandardItem::takeRow(...)
не только возвращает столбцы строки, но и удаляет их.
Перешел на функцию child(...) и всё заработало.
7  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 11:27
Сознательно не усложняю код для обработки иерархии.
Хочу на простом примере разобраться.
Сейчас ну никак не рисуются два нижних подзаголовка, хотя отладчик туда попадает.
И геометрия правильная.
8  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 22, 2019, 11:23
Чёт я сам с собою Улыбающийся
Иногда полезно просто высказаться.
paintSection константная функция и вызвать из нее слот для обновления соседней секции ну никак не удавалось.
Написал в своем классе константный сигнал и законнектил на неконстантный слот. Всё заработало.
Новый код paintSection

Код:
void CDataHeaderView::paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const
{
QStandardItem* pItem=m_headerModel.item(0,logicalIndex);
QVariant data=pItem->data();
QRect rc=rect;
    if(!data.isNull())//пока вот так ловлю "костыль"
    {
        pItem=m_headerModel.item(0,0);
rc.setLeft(sectionPosition(0));
rc.setWidth(sectionSize(0));
    }

    //Теперь начинаю разбирать новости
int colCount=pItem->columnCount();//ловлю элементы с вложенными колонками


if(colCount)//знаю про первую сложную колонку
    {
        int w=sectionSize(1);//индекс пока в тупую 1
        rc.setWidth(rc.width()+w);
        rc.setHeight(QHeaderView::sizeHint().height());

QRect rcs=rc;
QList<QStandardItem*>cols=pItem->takeRow(0);
for(int n=0;n<cols.size();n++)
{
QStandardItem* pColItem=cols[n];
rcs.setLeft(sectionPosition(n));
rcs.setWidth(sectionSize(n));
rcs.setTop(QHeaderView::sizeHint().height());
rcs.setHeight(QHeaderView::sizeHint().height());
pPainter->drawRect(rcs);
QString name=pColItem->text();
pPainter->drawText(rcs,Qt::AlignHCenter|Qt::AlignVCenter,name);
}
    }

    pPainter->drawRect(rc);
    pPainter->drawText(rc,Qt::AlignHCenter|Qt::AlignVCenter,pItem->text());

//if(colCount)//знаю про первую сложную колонку
    //{

    //}
if(!data.isNull())//пока вот так ловлю "костыль"
emit drawSection(0);
}
9  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 17:00
Спасибо за совет Улыбающийся Я же новичок:)
В архиве последняя версия.
10  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 16:13
Подожду ответа Улыбающийся
11  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 16:12
И всё бы хорошо, но стоит провести курсор над заголовком - начинаются неприятности.
Понятно, что я не рисую "костыльный" заголовок, но попытка его отрисовать -
тоже не спасает. Помогите форумчане Подмигивающий
12  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 16:09
Наблюдаем результат
13  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 16:07
Модифицирую код отрисовки
Код:
void CDataHeaderView::paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const
{
QStandardItem* pItem=m_headerModel.item(0,logicalIndex);
    //Теперь начинаю разбирать новости
int colCount=pItem->columnCount();//ловлю элементы с вложенными колонками

QRect rc=rect;
if(colCount)//знаю про первую сложную колонку
    {
        int w=sectionSize(1);//индекс пока в тупую 1
        rc.setWidth(rc.width()+w);
        rc.setHeight(QHeaderView::sizeHint().height());
    }
QVariant data=pItem->data();
    if(!data.isNull())//пока вот так ловлю "костыль"
    {
        return;//и ничего тут не рисую
    }
    pPainter->drawRect(rc);
    pPainter->drawText(rc,Qt::AlignHCenter|Qt::AlignVCenter,QString("%1").arg(pItem->text()));
}
14  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 16:05
Изменяю код
Код:
CDataHeaderView::CDataHeaderView(QWidget* pParent):
QHeaderView(Qt::Horizontal,pParent),
m_headerModel(this)
{
    m_rowCount=2;//пока без вычислений просто задаю две строки

    //Формирую сложный столбец
    QStandardItem* pItem=new QStandardItem(tr("Период"));
    QList<QStandardItem*> col;
    col.append(new QStandardItem(tr("Начало")));
    col.append(new QStandardItem(tr("Конец")));
    pItem->appendRow(col);//Добавил два подстолбца

    QList<QStandardItem*> columns;
    columns.append(pItem);//Сложный столбец в общую строку

    [color=red]//Искусственно добавляю еще один столбец
    pItem=new QStandardItem(tr("без имени"));//дополнительный столбец
    QVariant data(-1);//и пока "костыльно" его помечаю
    pItem->setData(data);
    columns.append(pItem);[/color]

    //Далее несколько формальных столбцов
    columns.append(new QStandardItem("Второй"));



    columns.append(new QStandardItem("Третий"));

    columns.append(new QStandardItem("Четвертый"));

    m_headerModel.appendRow(columns);//Добавляю строку в модель

    setModel(&m_headerModel);//Устанавливаю модель для CDataHeaderView
}
15  Qt / Вопросы новичков / Re: QTableWidget иерархические заголовки : Август 21, 2019, 14:07
У меня есть код с ручным добавлением и я его выложу,
 но может это уже "костыль"? Что я на данном этапе не так делаю?
Страниц: [1] 2

Страница сгенерирована за 0.062 секунд. Запросов: 23.