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. How to set Checkbox in header of one column in QtreeView
Forum Updated to NodeBB v4.3 + New Features

How to set Checkbox in header of one column in QtreeView

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 5 Posters 5.9k Views 3 Watching
  • 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.
  • Q Offline
    Q Offline
    Qt Enthusiast
    wrote on last edited by
    #1

    Hi All
    We need to set checkbox in header of one of the columns . I have following class

    class MyHeader : public QHeaderView
    {
    public:
    MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
    {}

    protected:
    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
    {
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();
    if (logicalIndex == 0)
    {
    QStyleOptionButton option;
    option.rect = QRect(10,10,10,10);
    if (isOn)
    option.state = QStyle::State_On;
    else
    option.state = QStyle::State_Off;
    this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
    }

    }
    void mousePressEvent(QMouseEvent *event)
    {
    if (isOn)
    isOn = false;
    else
    isOn = true;
    this->update();
    QHeaderView::mousePressEvent(event);
    }
    private:
    bool isOn;
    };

    class myView::QTreeView {

    }

    MyView::GQInstView(QWidget* dparent)
    : QTreeView(dparent), {

    }

    The tree View has three columns . How to set header for first column in treeView

    RatzzR raven-worxR 2 Replies Last reply
    0
    • Q Qt Enthusiast

      Hi All
      We need to set checkbox in header of one of the columns . I have following class

      class MyHeader : public QHeaderView
      {
      public:
      MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
      {}

      protected:
      void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
      {
      painter->save();
      QHeaderView::paintSection(painter, rect, logicalIndex);
      painter->restore();
      if (logicalIndex == 0)
      {
      QStyleOptionButton option;
      option.rect = QRect(10,10,10,10);
      if (isOn)
      option.state = QStyle::State_On;
      else
      option.state = QStyle::State_Off;
      this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
      }

      }
      void mousePressEvent(QMouseEvent *event)
      {
      if (isOn)
      isOn = false;
      else
      isOn = true;
      this->update();
      QHeaderView::mousePressEvent(event);
      }
      private:
      bool isOn;
      };

      class myView::QTreeView {

      }

      MyView::GQInstView(QWidget* dparent)
      : QTreeView(dparent), {

      }

      The tree View has three columns . How to set header for first column in treeView

      RatzzR Offline
      RatzzR Offline
      Ratzz
      wrote on last edited by
      #2

      @Qt-Enthusiast
      Is this the same post of https://forum.qt.io/topic/67574/can-we-have-checkbox-in-header-of-qtreeview-along-with-sorting-symbol/

      --Alles ist gut.

      1 Reply Last reply
      2
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3
        • The tree View has three columns . How to set header for first column in treeView

        Hi
        I do not think you can replace for just column 1
        You can set for treeview using
        http://doc.qt.io/qt-5/qtreeview.html#setHeader
        and that be for all columns.

        1 Reply Last reply
        2
        • Q Qt Enthusiast

          Hi All
          We need to set checkbox in header of one of the columns . I have following class

          class MyHeader : public QHeaderView
          {
          public:
          MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
          {}

          protected:
          void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
          {
          painter->save();
          QHeaderView::paintSection(painter, rect, logicalIndex);
          painter->restore();
          if (logicalIndex == 0)
          {
          QStyleOptionButton option;
          option.rect = QRect(10,10,10,10);
          if (isOn)
          option.state = QStyle::State_On;
          else
          option.state = QStyle::State_Off;
          this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
          }

          }
          void mousePressEvent(QMouseEvent *event)
          {
          if (isOn)
          isOn = false;
          else
          isOn = true;
          this->update();
          QHeaderView::mousePressEvent(event);
          }
          private:
          bool isOn;
          };

          class myView::QTreeView {

          }

          MyView::GQInstView(QWidget* dparent)
          : QTreeView(dparent), {

          }

          The tree View has three columns . How to set header for first column in treeView

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @Qt-Enthusiast

          1. set your custom header view to your items widget like @mrjj said
          2. instead of using "isOn" in the header class, query the model's headerData() method for the Qt::CheckStateRole
          3. in your model return the corresponding check state in headerData(). For column 1 return Qt::Checked, when you don't want to display a checkbox at all return an invalid QVariant

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          Q 1 Reply Last reply
          3
          • Q Offline
            Q Offline
            Qt Enthusiast
            wrote on last edited by
            #5

            @raven-worx said:

            odel's headerData() method for the Qt::CheckStateRole
            in your model return the corresponding check state in

            how to get model pointer

            class MyHeader : public QHeaderView
            {
            public:
            MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
            {}

            protected:
            void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
            {
            painter->save();
            QHeaderView::paintSection(painter, rect, logicalIndex);
            painter->restore();
            if (logicalIndex == 0)
            {
            QStyleOptionButton option;
            option.rect = QRect(10,10,10,10);
            if (isOn)
            option.state = QStyle::State_On;
            else
            option.state = QStyle::State_Off;
            this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
            }

            }
            void mousePressEvent(QMouseEvent *event)
            {
            if (isOn)
            isOn = false;
            else
            isOn = true;
            this->update();
            QHeaderView::mousePressEvent(event);
            }
            private:
            bool isOn;
            };

            raven-worxR 1 Reply Last reply
            0
            • Q Qt Enthusiast

              @raven-worx said:

              odel's headerData() method for the Qt::CheckStateRole
              in your model return the corresponding check state in

              how to get model pointer

              class MyHeader : public QHeaderView
              {
              public:
              MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
              {}

              protected:
              void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
              {
              painter->save();
              QHeaderView::paintSection(painter, rect, logicalIndex);
              painter->restore();
              if (logicalIndex == 0)
              {
              QStyleOptionButton option;
              option.rect = QRect(10,10,10,10);
              if (isOn)
              option.state = QStyle::State_On;
              else
              option.state = QStyle::State_Off;
              this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
              }

              }
              void mousePressEvent(QMouseEvent *event)
              {
              if (isOn)
              isOn = false;
              else
              isOn = true;
              this->update();
              QHeaderView::mousePressEvent(event);
              }
              private:
              bool isOn;
              };

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              @Qt-Enthusiast said:

              how to get model pointer

              since QHeaderView derives from QAbstractItemView, you are doing it the same way you would do for table/trees/lists/... with the model() method
              This model is the same as the item view widget has also set.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • raven-worxR raven-worx

                @Qt-Enthusiast

                1. set your custom header view to your items widget like @mrjj said
                2. instead of using "isOn" in the header class, query the model's headerData() method for the Qt::CheckStateRole
                3. in your model return the corresponding check state in headerData(). For column 1 return Qt::Checked, when you don't want to display a checkbox at all return an invalid QVariant
                Q Offline
                Q Offline
                Qt Enthusiast
                wrote on last edited by
                #7

                @raven-worx

                #include <QApplication>
                #include <QAbstractTableModel>
                #include <QSortFilterProxyModel>
                #include <QInputDialog>
                #include <QTableView>
                #include <QGridLayout>
                #include <QPushButton>
                #include <QDebug>
                #include <QHeaderView>
                #include <QStyle>
                #include <QPainter>
                #include <QMouseEvent>
                #include <QTreeView>

                class MyHeader : public QHeaderView
                {
                public:
                MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
                {}

                protected:
                void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
                {
                painter->save();
                QHeaderView::paintSection(painter, rect, logicalIndex);
                painter->restore();
                if (logicalIndex == 1 )
                {
                QStyleOptionButton option;
                option.rect = QRect(10,10,10,10);
                isOn = model()->headerData(1,Qt::Horizontal, Qt::CheckStateRole);
                if (isOn)
                option.state = QStyle::State_On;
                else
                option.state = QStyle::State_Off;
                this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
                }

                }
                void mousePressEvent(QMouseEvent *event)
                {

                if (isOn)
                  isOn = false;
                else
                  isOn = true;
                this->update();
                QHeaderView::mousePressEvent(event);
                

                }
                private:
                bool isOn;
                };

                class Vehicle {
                QString m_make, m_model, m_registrationNumber;
                public:
                Vehicle(const QString & make, const QString & model, const QString & registrationNumber = QString()) :
                m_make(make), m_model(model), m_registrationNumber(registrationNumber) {}
                QString make() const { return m_make; }
                QString model() const { return m_model; }
                QString registrationNumber() const { return m_registrationNumber; }
                bool isRegistered() const { return !m_registrationNumber.isEmpty(); }
                };

                class VehicleModel : public QAbstractTableModel {
                QList<Vehicle> m_data;
                public:
                VehicleModel(QObject * parent = 0) : QAbstractTableModel(parent) {}
                int rowCount(const QModelIndex &) const { return m_data.count(); }
                int columnCount(const QModelIndex &) const { return 3; }
                QVariant data(const QModelIndex &index, int role) const {
                if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
                const Vehicle & vehicle = m_data[index.row()];
                switch (index.column()) {
                case 0: return vehicle.make();
                case 1: return vehicle.model();
                case 2: return vehicle.registrationNumber();
                default: return QVariant();
                };
                }
                QVariant headerData(int section, Qt::Orientation orientation, int role) const {
                if(role == Qt::CheckStateRole && orientation == Qt::Horizontal) {
                switch (section) {
                case 0: return Qt::Unchecked;
                case 1: return Qt::Checked;
                case 2: return Qt::Unchecked;
                default: return QVariant();
                }

                    }
                    if (orientation != Qt::Horizontal) return QVariant();
                    if (role != Qt::) return QVariant();
                    switch (section) {
                    case 0: return "Make";
                    case 1: return "Model";
                    case 2: return "Reg.#";
                    default: return QVariant();
                    }
                }
                void append(const Vehicle & vehicle) {
                    beginInsertRows(QModelIndex(), m_data.count(), m_data.count());
                    m_data.append(vehicle);
                    endInsertRows();
                }
                

                };

                class Widget : public QWidget {

                VehicleModel m_model;
                QSortFilterProxyModel m_proxy;
                Q_SLOT void setFilter() {
                    QInputDialog * dialog = new QInputDialog(this);
                    dialog->setLabelText("Enter registration number fragment to filter on. Leave empty to clear filter.");
                    dialog->setInputMode(QInputDialog::TextInput);
                    dialog->open(&m_proxy, SLOT(setFilterFixedString(QString)));
                    dialog->setAttribute(Qt::WA_DeleteOnClose);
                }
                

                public:
                Widget() {
                QGridLayout * layout = new QGridLayout(this);
                QTreeView view = new QTreeView;
                MyHeader
                myH = new MyHeader(Qt::Horizontal);
                view->setHeader(myH);
                layout->addWidget(view, 0, 0, 1, 1);
                QPushButton * btn = new QPushButton("Filter");
                layout->addWidget(btn, 1, 0, 1, 1);
                m_model.append(Vehicle("Volvo", "240", "SQL8941"));
                m_model.append(Vehicle("Volvo", "850"));
                m_model.append(Vehicle("Volvo", "940", "QRZ1321"));
                m_model.append(Vehicle("Volvo", "960", "QRZ1628"));
                view->setModel(&m_model);
                }
                };

                int main(int argc, char *argv[])
                {
                QApplication a(argc, argv);
                Widget w;
                w.show();
                return a.exec();
                }

                could you guide me on the same how to have checkbox in above code as per your inputs

                raven-worxR 1 Reply Last reply
                0
                • S Offline
                  S Offline
                  Sam
                  wrote on last edited by
                  #8

                  Have a look at this Qt blog https://blog.qt.io/blog/2012/09/28/qt-support-weekly-27-widgets-on-a-header/

                  1 Reply Last reply
                  0
                  • Q Qt Enthusiast

                    @raven-worx

                    #include <QApplication>
                    #include <QAbstractTableModel>
                    #include <QSortFilterProxyModel>
                    #include <QInputDialog>
                    #include <QTableView>
                    #include <QGridLayout>
                    #include <QPushButton>
                    #include <QDebug>
                    #include <QHeaderView>
                    #include <QStyle>
                    #include <QPainter>
                    #include <QMouseEvent>
                    #include <QTreeView>

                    class MyHeader : public QHeaderView
                    {
                    public:
                    MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
                    {}

                    protected:
                    void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
                    {
                    painter->save();
                    QHeaderView::paintSection(painter, rect, logicalIndex);
                    painter->restore();
                    if (logicalIndex == 1 )
                    {
                    QStyleOptionButton option;
                    option.rect = QRect(10,10,10,10);
                    isOn = model()->headerData(1,Qt::Horizontal, Qt::CheckStateRole);
                    if (isOn)
                    option.state = QStyle::State_On;
                    else
                    option.state = QStyle::State_Off;
                    this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
                    }

                    }
                    void mousePressEvent(QMouseEvent *event)
                    {

                    if (isOn)
                      isOn = false;
                    else
                      isOn = true;
                    this->update();
                    QHeaderView::mousePressEvent(event);
                    

                    }
                    private:
                    bool isOn;
                    };

                    class Vehicle {
                    QString m_make, m_model, m_registrationNumber;
                    public:
                    Vehicle(const QString & make, const QString & model, const QString & registrationNumber = QString()) :
                    m_make(make), m_model(model), m_registrationNumber(registrationNumber) {}
                    QString make() const { return m_make; }
                    QString model() const { return m_model; }
                    QString registrationNumber() const { return m_registrationNumber; }
                    bool isRegistered() const { return !m_registrationNumber.isEmpty(); }
                    };

                    class VehicleModel : public QAbstractTableModel {
                    QList<Vehicle> m_data;
                    public:
                    VehicleModel(QObject * parent = 0) : QAbstractTableModel(parent) {}
                    int rowCount(const QModelIndex &) const { return m_data.count(); }
                    int columnCount(const QModelIndex &) const { return 3; }
                    QVariant data(const QModelIndex &index, int role) const {
                    if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
                    const Vehicle & vehicle = m_data[index.row()];
                    switch (index.column()) {
                    case 0: return vehicle.make();
                    case 1: return vehicle.model();
                    case 2: return vehicle.registrationNumber();
                    default: return QVariant();
                    };
                    }
                    QVariant headerData(int section, Qt::Orientation orientation, int role) const {
                    if(role == Qt::CheckStateRole && orientation == Qt::Horizontal) {
                    switch (section) {
                    case 0: return Qt::Unchecked;
                    case 1: return Qt::Checked;
                    case 2: return Qt::Unchecked;
                    default: return QVariant();
                    }

                        }
                        if (orientation != Qt::Horizontal) return QVariant();
                        if (role != Qt::) return QVariant();
                        switch (section) {
                        case 0: return "Make";
                        case 1: return "Model";
                        case 2: return "Reg.#";
                        default: return QVariant();
                        }
                    }
                    void append(const Vehicle & vehicle) {
                        beginInsertRows(QModelIndex(), m_data.count(), m_data.count());
                        m_data.append(vehicle);
                        endInsertRows();
                    }
                    

                    };

                    class Widget : public QWidget {

                    VehicleModel m_model;
                    QSortFilterProxyModel m_proxy;
                    Q_SLOT void setFilter() {
                        QInputDialog * dialog = new QInputDialog(this);
                        dialog->setLabelText("Enter registration number fragment to filter on. Leave empty to clear filter.");
                        dialog->setInputMode(QInputDialog::TextInput);
                        dialog->open(&m_proxy, SLOT(setFilterFixedString(QString)));
                        dialog->setAttribute(Qt::WA_DeleteOnClose);
                    }
                    

                    public:
                    Widget() {
                    QGridLayout * layout = new QGridLayout(this);
                    QTreeView view = new QTreeView;
                    MyHeader
                    myH = new MyHeader(Qt::Horizontal);
                    view->setHeader(myH);
                    layout->addWidget(view, 0, 0, 1, 1);
                    QPushButton * btn = new QPushButton("Filter");
                    layout->addWidget(btn, 1, 0, 1, 1);
                    m_model.append(Vehicle("Volvo", "240", "SQL8941"));
                    m_model.append(Vehicle("Volvo", "850"));
                    m_model.append(Vehicle("Volvo", "940", "QRZ1321"));
                    m_model.append(Vehicle("Volvo", "960", "QRZ1628"));
                    view->setModel(&m_model);
                    }
                    };

                    int main(int argc, char *argv[])
                    {
                    QApplication a(argc, argv);
                    Widget w;
                    w.show();
                    return a.exec();
                    }

                    could you guide me on the same how to have checkbox in above code as per your inputs

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    @Qt-Enthusiast said:

                    could you guide me on the same how to have checkbox in above code as per your inputs

                    i just give you some snippets. I leave it to you to check the rest out, since it's pretty simple.

                    in the header:

                    void MyHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
                    {
                    painter->save();
                    QHeaderView::paintSection(painter, rect, logicalIndex);
                    painter->restore();
                    
                    QVariant headerCheckState = model()->headerData(logicalIndex, Qt::Horizontal, Qt::CheckStateRole);
                    
                    if( headerCheckState .isValid() )  //only paint the checkbox if the model returned a valid qvariant
                    {
                    Qt::CheckState check = static_cast<Qt::CheckState>( headerCheckState.toInt() );
                    QStyleOptionButton option;
                    option.rect = QRect(10,10,10,10);
                    if ( checkState == Qt::Checked )
                          option.state = QStyle::State_On;
                    else
                          option.state = QStyle::State_Off;
                    this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
                    }
                    

                    in the model:

                    QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role ) const
                    {
                         if( orientation == Qt::Horizontal )
                         {
                                   switch( role )
                                   {
                                          case Qt::CheckStateRole:
                                          {
                                                     if( section == XXX )  // here you need to check which columns you want to display the checkbox
                                                     {
                                                            return QVariant::fromValue<int>(Qt::Checked);
                                                     }
                                          }
                                          break;
                                   }
                         }
                    
                          return QHeaderView::headerData(section,orientation,role);
                    }
                    

                    This way a checkbox is only displayed when you return a valid QVariant:

                    Invalid QVariant -> no checkbox
                    QVariant with Qt::CheckedState -> checked checkbox
                    QVariant with other value -> unchecked checkbox

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    1

                    • Login

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