Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableWidget, 1 header for 2 columns
Forum Update on Monday, May 27th 2025

QTableWidget, 1 header for 2 columns

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 4.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Patou355
    wrote on 7 Oct 2016, 08:28 last edited by
    #1

    Hello all.

    I use a QTableWidget and I need to have one header for 2 columns. See below (achieved with cheating):

    text alternatif

    I didn't find any easy to implement solution. Who knows what I can do?

    1 Reply Last reply
    0
    • V Offline
      V Offline
      VRonin
      wrote on 7 Oct 2016, 09:11 last edited by VRonin 10 Jul 2016, 09:11
      #2

      It's not extra complicated, you need to subclass QHeaderView, see http://stackoverflow.com/questions/22755171/spanning-horizontal-header-in-qt

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      3
      • P Offline
        P Offline
        Patou355
        wrote on 7 Oct 2016, 09:39 last edited by
        #3

        Right, I'll have to do it...

        Thanks!

        1 Reply Last reply
        0
        • P Offline
          P Offline
          Patou355
          wrote on 9 Dec 2016, 10:16 last edited by
          #4

          Hi all.
          I'm back to this topic because I got back working on it.
          I took the code above and splitted it into headers and source files. And I brought some modifications. Right.
          See below :
          header.h

          #ifndef HEADER_H
          #define HEADER_H
          
          #endif // HEADER_H
          
          #include <QtGui>
          #include <QHeaderView>
          #include <QTableWidget>
          #include "headermodel.h"
          
          class Header : public QHeaderView
          {
              Q_OBJECT
          public:
              Header(QHeaderView *header, QWidget *parent = 0);
              void setHeaderCount(int cnt);
              int headerCount();
          
          public slots:
              void updateSizes();
              void updateOffset();
          
          protected:
              bool eventFilter(QObject *o, QEvent *e);
          
          private:
              int getSectionSizes(int first, int second);
          
              QHeaderView *mainHeader;
          };
          

          header.cpp

          #ifndef HEADER_H
          #define HEADER_H
          
          #endif // HEADER
          
          #include "header.h"
          
          
              Header::Header(QHeaderView *header, QWidget *parent) : QHeaderView(Qt::Horizontal, header), mainHeader(header) {
                  setModel(new HeaderModel(this));
                  // This example uses hardcoded groups, you can extend
                  // this yourself to save the groups
                  // Group 1 is 0-2 and Group 2 is 3-4
          //        resizeSection(0, getSectionSizes(0, 2));
          //        resizeSection(1, getSectionSizes(3, 4));
                  int i;
                  for (i = 0 ; i < this->headerCount() ; i++)
                      resizeSection(i, getSectionSizes(i,i+1));
          
                  connect(this, SIGNAL(sectionResized(int,int,int)), this, SLOT(updateSizes()));
          
                  setGeometry(0, 0, header->width(), header->height());
                  updateOffset();
                  mainHeader->installEventFilter(this);
              }
          
              void Header::setHeaderCount(int cnt){
              }
          
              int Header::headerCount(){
              }
          
          //    int Header::columnCount(const QModelIndex &parent) const {
          //        return 8;
          //    }
          
              void Header::updateSizes()
              {
                  setOffset(mainHeader->offset());
                  mainHeader->resizeSection(2, mainHeader->sectionSize(2) + (sectionSize(0) - getSectionSizes(0, 2)));
                  mainHeader->resizeSection(4, mainHeader->sectionSize(4) + (sectionSize(1) - getSectionSizes(3, 4)));
              }
          
              void Header::updateOffset()
              {
                  setOffset(mainHeader->offset());
              }
          
              bool Header::eventFilter(QObject *o, QEvent *e)
              {
                  if (o == mainHeader) {
                      if (e->type() == QEvent::Resize) {
                          setOffset(mainHeader->offset());
                          setGeometry(0, 0, mainHeader->width(), mainHeader->height());
                      }
                      return false;
                  }
                  return QHeaderView::eventFilter(o, e);
              }
          
              int Header::getSectionSizes(int first, int second)
              {
                  int size = 0;
                  for (int a=first;a<=second;++a)
                      size += mainHeader->sectionSize(a);
                  return size;
              }
          

          headermodel.h

          #ifndef HEADERMODEL_H
          #define HEADERMODEL_H
          
          #endif // HEADERMODEL_H
          
          #include <QtGui>
          #include <QHeaderView>
          #include <QTableWidget>
          
          class QTableWidget;
          class HeaderModel : public QAbstractItemModel {
          public:
              HeaderModel(QObject *parent = 0);
              int columnCount(const QModelIndex &parent = QModelIndex()) const;
              QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
              QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
              QModelIndex parent(const QModelIndex &index) const;
              int rowCount(const QModelIndex &parent = QModelIndex()) const;
              void setHeaderCount(int cnt);
              int headerCount();
          
          protected:
              int headersCount = 6;
          };
          

          headermodel.cpp

          #ifndef HEADERMODEL_H
          #define HEADERMODEL_H
          
          #endif // HEADERMODEL_H
          
          #include "headermodel.h"
          
              HeaderModel::HeaderModel(QObject *parent) : QAbstractItemModel(parent) {
              }
          
              int HeaderModel::columnCount(const QModelIndex &parent) const {
                  return headersCount;
              }
          
              QVariant HeaderModel::data(const QModelIndex &index, int role) const {
                  return QVariant();
              }
          
              QModelIndex HeaderModel::index(int row, int column, const QModelIndex &parent) const {
                  return QModelIndex();
              }
          
              QModelIndex HeaderModel::parent(const QModelIndex &index) const {
                  return QModelIndex();
              }
          
              int HeaderModel::rowCount(const QModelIndex &parent) const {
                  return 0;
              }
          
              void HeaderModel::setHeaderCount(int cnt){
                  headersCount = cnt;
              }
          
              int HeaderModel::headerCount(){
                  return headersCount;
              }
          

          And the main.cpp :

          #include "mainwindow.h"
          #include <QApplication>
          #include <QVBoxLayout>
          #include <QTableWidget>
          #include "header.h"
          
          int main(int argc, char *argv[])
          {
              int colCount = 12;
              QApplication a(argc, argv);
              QWidget w;
              QVBoxLayout *vbox = new QVBoxLayout;
              QTableWidget *tw = new QTableWidget(10, colCount);
              Header *h = new Header(tw->horizontalHeader());
              h->setHeaderCount(2);
          
              vbox->addWidget(tw);
              w.setLayout(vbox);
              w.setMinimumWidth(1600);
              w.setMinimumHeight(600);
              w.show();
          
              return a.exec();
          }
          

          headersCount is supposed to be, as you guess, the numbers of headers on the top, and void setHeaderCount(int cnt) sets it.
          The problem is that the effective number of headers is the value returned by HeaderModel's virtual QAbstractItemModel-herited columnCount(). I don't understand the mechanism, but if columnCount() returns n, there would be n headers.

          That's why I created a protected class member int headersCount in order to set the the number of headers through columnCount()

              int HeaderModel::columnCount(const QModelIndex &parent) const {
                  return headersCount;
              }
          

          And then I created a

          void HeaderModel::setHeaderCount(int cnt){
              headersCount = cnt;
          }
          

          to set it.
          But h->setHeaderCount(2); is inoperative. I suppose because setting headersCount after the construction of the headers is too late.

          My goal is to have an easy-to-use header class out of the code above but I don't know how to achieve it...

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved