QTableWidget, 1 header for 2 columns



  • 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?



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



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

    Thanks!



  • 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...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.