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

How to set Checkbox in header of one column in QtreeView

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 5 Posters 6.5k 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