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

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QTableWidget иерархические заголовки  (Прочитано 17754 раз)
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« : Август 20, 2019, 17:38 »

Не в первый раз звучит вопрос Улыбающийся
Значит, так и не решённый прежде.
Уберегите от флуда, но про иерархические заголовки решения не нашёл.
Опирался на сообщения аж 2008 года.
http://www.prog.org.ru/topic_6637_15.html
Написал всё в рамках изложенной стратегии Zmeishe.
Всё работает, но есть нюансы.
У меня условия - QT 4.8.0.
Не претендую на авторские права.
Готов выложить свой код, поскольку появились вопросы.
Если есть кто живой в этой теме, то помогите неопытному.
« Последнее редактирование: Август 21, 2019, 13:54 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #1 : Август 21, 2019, 13:48 »

И так, всё по порядку.
Это .pro - файл

Код:
QT       += core

TARGET = testTable
TEMPLATE = app

DESTDIR = ../

SOURCES += ./source/main.cpp \
           ./source/testTable.cpp

 
HEADERS += ./include/testTable.h
          
 
FORMS += ./ui/testTable.ui

INCLUDEPATH += ./include/

INCLUDEPATH += ./tmp/release/moc \
    ./tmp/release/uic \
    ./tmp/release/rcc

MOC_DIR += ./tmp/release/moc
OBJECTS_DIR += ./tmp/release/objecs
UI_DIR += ./tmp/release/uic
RCC_DIR += ./tmp/release/rcc

это testTable.ui


Код:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>testTable</class>
 <widget class="QMainWindow" name="testTable">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>650</width>
    <height>428</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Тестирование таблицы</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTableWidget" name="tableWidget"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>650</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
« Последнее редактирование: Август 21, 2019, 16:53 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #2 : Август 21, 2019, 13:50 »

Содержимое main.cpp

Код:
#include "testTable.h"
#include <QTextCodec>
#include <QTranslator>

int main(int argc, char* argv[])
{

    // UNICODE
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    
    QApplication app(argc, argv);
    QTranslator qtTranslator;
    qtTranslator.load("qt_" + QLocale::system().name(),"./translations");

    app.installTranslator(&qtTranslator);

    CTestTable ctrlWindow;
    ctrlWindow.show();

    return app.exec();
}
« Последнее редактирование: Август 21, 2019, 16:51 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #3 : Август 21, 2019, 13:51 »

Содержимое testTable.h

Код:
#ifndef TEST_TABLE_H_21_08_2019_11_49
#define TEST_TABLE_H_21_08_2019_11_49

#include "ui_testTable.h"

#include <QStandardItemModel>

class CDataHeaderView: public QHeaderView
{
    Q_OBJECT

public:
    CDataHeaderView(QWidget* pParent);
    ~CDataHeaderView();

protected:
    virtual QSize sizeHint() const;
    virtual void paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const;

private:
    QStandardItemModel m_headerModel;
    int m_rowCount;
};

class CTestTable:public QMainWindow, public Ui::testTable
{
    Q_OBJECT

public:
    CTestTable();
    ~CTestTable();
};

#endif // TEST_TABLE_H_21_08_2019_11_49
« Последнее редактирование: Август 21, 2019, 16:51 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #4 : Август 21, 2019, 13:52 »

Содержимое testTable.cpp

Код:
#include "testTable.h"
#include <QPainter>

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);//Сложный столбец в общую строку

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

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

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

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

    setModel(&m_headerModel);//Устанавливаю модель для CDataHeaderView
}

CDataHeaderView::~CDataHeaderView()
{

}

QSize CDataHeaderView::sizeHint() const
{
    QSize size=QHeaderView::sizeHint();
    size.rheight()*=m_rowCount;
    return size;
}


void CDataHeaderView::paintSection(QPainter* pPainter,const QRect& rect,int logicalIndex) const
{
    //Пока, для появления ощущений, рисую прямоугольник и вывожу тест
    QStandardItem* pItem=m_headerModel.item(0,logicalIndex);
    pPainter->drawRect(rect);
    pPainter->drawText(rect,Qt::AlignHCenter|Qt::AlignVCenter,QString("%1").arg(pItem->text()));
}


CTestTable::CTestTable():
QMainWindow(NULL)
{
    setupUi(this);
    //Устанавливаю горизонтальный заголовок для таблицы
    tableWidget->setHorizontalHeader(new CDataHeaderView(tableWidget));
}

CTestTable::~CTestTable()
{
    
}
« Последнее редактирование: Август 21, 2019, 16:50 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #5 : Август 21, 2019, 13:54 »

Реализую стратегию выше упомянутого Zmeishe, за что ему очень благодарен.
« Последнее редактирование: Август 21, 2019, 14:08 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #6 : Август 21, 2019, 14:02 »

Наблюдаем результат
« Последнее редактирование: Август 21, 2019, 16:54 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #7 : Август 21, 2019, 14:05 »

Получается, что QTableWidget не видит вложенные столбцы,
а значит мне их нужно добавлять вручную?
Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #8 : Август 21, 2019, 14:07 »

У меня есть код с ручным добавлением и я его выложу,
 но может это уже "костыль"? Что я на данном этапе не так делаю?
« Последнее редактирование: Август 21, 2019, 14:11 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #9 : Август 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
}
« Последнее редактирование: Август 21, 2019, 16:49 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #10 : Август 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()));
}
« Последнее редактирование: Август 21, 2019, 17:08 от Иваныч » Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #11 : Август 21, 2019, 16:09 »

Наблюдаем результат
Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #12 : Август 21, 2019, 16:12 »

И всё бы хорошо, но стоит провести курсор над заголовком - начинаются неприятности.
Понятно, что я не рисую "костыльный" заголовок, но попытка его отрисовать -
тоже не спасает. Помогите форумчане Подмигивающий
Записан
Иваныч
Новичок

Offline Offline

Сообщений: 23


Просмотр профиля
« Ответ #13 : Август 21, 2019, 16:13 »

Подожду ответа Улыбающийся
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #14 : Август 21, 2019, 16:50 »

Лучше упакуйте все необходимые файлы проекта в архив и "вложите" в сообщение, тогда может кто-нибудь и посмотрит его.
Записан

Пока сам не сделаешь...
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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