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. Add a QCheckBox as a header to a QTableWidget
Forum Updated to NodeBB v4.3 + New Features

Add a QCheckBox as a header to a QTableWidget

Scheduled Pinned Locked Moved Solved General and Desktop
23 Posts 6 Posters 9.4k 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.
  • C Offline
    C Offline
    Chris Kawa
    Lifetime Qt Champion
    wrote on 31 May 2021, 09:44 last edited by
    #11

    Just to add to what @mrjj said - a click is when you press and release mouse button on the same widget.

    Having said that you shouldn't just always emit it in release event. You should record in press event which section was pressed, then in release check if it's the same one and only then emit a clicked signal.

    If you release on different section than the one you press on nothing should happen. This is for the purpose of user realizing mid-click that they pressed on the wrong area. They can then move the mouse away and release and this is basically cancelling the click.

    H 1 Reply Last reply 31 May 2021, 16:06
    3
    • C Chris Kawa
      31 May 2021, 09:44

      Just to add to what @mrjj said - a click is when you press and release mouse button on the same widget.

      Having said that you shouldn't just always emit it in release event. You should record in press event which section was pressed, then in release check if it's the same one and only then emit a clicked signal.

      If you release on different section than the one you press on nothing should happen. This is for the purpose of user realizing mid-click that they pressed on the wrong area. They can then move the mouse away and release and this is basically cancelling the click.

      H Offline
      H Offline
      hbatalha
      wrote on 31 May 2021, 16:06 last edited by hbatalha
      #12

      @Chris-Kawa @mrjj Done.

      Is there a way to control the checkbox programatically, sending the signal and get the checkbox checked. I need the checkbox default state to be checked and I need to uncheck it when I uncheck any checkbox in the rows in the qtablewidget. Like in the OP image.

      M 1 Reply Last reply 31 May 2021, 16:16
      1
      • H hbatalha
        31 May 2021, 16:06

        @Chris-Kawa @mrjj Done.

        Is there a way to control the checkbox programatically, sending the signal and get the checkbox checked. I need the checkbox default state to be checked and I need to uncheck it when I uncheck any checkbox in the rows in the qtablewidget. Like in the OP image.

        M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 31 May 2021, 16:16 last edited by
        #13

        @hbatalha
        hi
        it uses the model so you can just set it in model

         model->setHeaderData(section, orientation(), true/false, Qt::CheckStateRole);
        
        H 1 Reply Last reply 31 May 2021, 16:22
        1
        • M mrjj
          31 May 2021, 16:16

          @hbatalha
          hi
          it uses the model so you can just set it in model

           model->setHeaderData(section, orientation(), true/false, Qt::CheckStateRole);
          
          H Offline
          H Offline
          hbatalha
          wrote on 31 May 2021, 16:22 last edited by
          #14

          @mrjj said in Add a QCheckBox as a header to a QTableWidget:

          model->setHeaderData(section, orientation(), true/false, Qt::CheckStateRole);

          what would be the value of section?

          M 1 Reply Last reply 31 May 2021, 16:24
          0
          • H hbatalha
            31 May 2021, 16:22

            @mrjj said in Add a QCheckBox as a header to a QTableWidget:

            model->setHeaderData(section, orientation(), true/false, Qt::CheckStateRole);

            what would be the value of section?

            M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 31 May 2021, 16:24 last edited by mrjj
            #15

            @hbatalha
            just 0,1,2,3,4 for the sections.
            unless you allow drag to reorder then you have to use
            https://doc.qt.io/qt-5/qheaderview.html#visualIndex
            to map to the right index/ID

            H L 2 Replies Last reply 31 May 2021, 16:31
            2
            • M mrjj
              31 May 2021, 16:24

              @hbatalha
              just 0,1,2,3,4 for the sections.
              unless you allow drag to reorder then you have to use
              https://doc.qt.io/qt-5/qheaderview.html#visualIndex
              to map to the right index/ID

              H Offline
              H Offline
              hbatalha
              wrote on 31 May 2021, 16:31 last edited by
              #16

              @mrjj I gave it 0.

              Everything is working perfect.

              Thank you all!!!

              1 Reply Last reply
              1
              • M mrjj
                31 May 2021, 16:24

                @hbatalha
                just 0,1,2,3,4 for the sections.
                unless you allow drag to reorder then you have to use
                https://doc.qt.io/qt-5/qheaderview.html#visualIndex
                to map to the right index/ID

                L Offline
                L Offline
                lisukovigor492
                wrote on 31 May 2021, 16:41 last edited by lisukovigor492 6 Aug 2021, 13:31
                #17

                @mrjj just 0,1,2,3,4 for the sections.
                unless you allow drag to reorder then you have to use
                https://doc.qt.io/qt-5/qheaderview.html#visualIndex https://www.worktime.com/employee-time-tracking-software
                to map to the right index/ID

                Hello,
                the question is too simple, but I'm a beginner, please tell me what parameters of the indexer should be?

                Thank you

                M 1 Reply Last reply 31 May 2021, 16:45
                0
                • L lisukovigor492
                  31 May 2021, 16:41

                  @mrjj just 0,1,2,3,4 for the sections.
                  unless you allow drag to reorder then you have to use
                  https://doc.qt.io/qt-5/qheaderview.html#visualIndex https://www.worktime.com/employee-time-tracking-software
                  to map to the right index/ID

                  Hello,
                  the question is too simple, but I'm a beginner, please tell me what parameters of the indexer should be?

                  Thank you

                  M Offline
                  M Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on 31 May 2021, 16:45 last edited by mrjj
                  #18

                  @lisukovigor492
                  Hi
                  you mean for the
                  int QHeaderView::visualIndex(int logicalIndex) ?

                  well its for when its reordered. then say index 5 is in front and then comes 2 and so on.
                  The issues is they are no longer in order.

                  so you use

                  int realIndex = HeaderView->visualIndex(0)
                  and IF the header is reorderd it will then tell you what index is a section 0.
                  like 7. or what ever what dragged there.

                  there is also
                  int QHeaderView::logicalIndex(int visualIndex)

                  I might recall it reverse. :) but they allow to map between the sections you see on screen and their real Id/indexs.

                  But this is only important if you allow user to move the sections around.

                  To get to know them, you could enable it and then
                  drag some around and the see what therse functions returns for the sections.

                  its all just integers values so nothing fancy at all.

                  1 Reply Last reply
                  0
                  • C Chris Kawa
                    30 May 2021, 15:02

                    Sigh... right, don't you just love when internet examples are buggy? :P

                    Here's a fixed version:

                    class MyHeader : public QHeaderView
                    {
                    public:
                        using QHeaderView::QHeaderView;
                    
                    protected:
                    
                        void paintSection(QPainter* painter, const QRect &rect, int logicalIndex) const override
                        {
                            painter->save();
                            QHeaderView::paintSection(painter, rect, logicalIndex);
                            painter->restore();
                    
                            if (model() && logicalIndex >= 0)
                            {
                                QStyleOptionButton option;
                                option.init(this);
                    
                                QRect checkbox_rect = style()->subElementRect(QStyle::SubElement::SE_CheckBoxIndicator, &option, this);
                                checkbox_rect.moveCenter(rect.center());
                    
                                bool checked = model()->headerData(logicalIndex, orientation(), Qt::CheckStateRole).toBool();
                    
                                option.rect = checkbox_rect;
                                option.state = checked ? QStyle::State_On : QStyle::State_Off;
                    
                                style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
                            }
                        }
                    
                        void mouseReleaseEvent(QMouseEvent* event) override
                        {
                            QHeaderView::mouseReleaseEvent(event);
                            if(model())
                            {
                                int section = logicalIndexAt(event->pos());
                                if (section >= 0)
                                {
                                    bool checked = model()->headerData(section, orientation(), Qt::CheckStateRole).toBool();
                                    model()->setHeaderData(section, orientation(), !checked, Qt::CheckStateRole);
                                    viewport()->update();
                                }
                            }
                        }
                    };
                    

                    Just a note - for simplicity this version toggles the checkbox whenever you click anywhere in the header section. You should probably shrink this area to only the actual checkbox. You have all the info in the example - just get the checkbox rectangle and see if the click was inside it.

                    H Offline
                    H Offline
                    hbatalha
                    wrote on 18 Jun 2021, 17:38 last edited by
                    #19

                    @Chris-Kawa is there a way to change the checkbox border and mark color so it doesn't look grayed outScreenshot_1.png

                    I have tried

                    QPalette p(Qt::black);
                    style()->polish(p);
                    
                    painter->setPen(Qt::black);
                    painter->setBrush(Qt::back);
                    
                    option.palette = QPalette(Qt::black);
                    

                    But none of the above worked.
                    Is there a way to change its color?

                    C 1 Reply Last reply 18 Jun 2021, 19:49
                    0
                    • H hbatalha
                      18 Jun 2021, 17:38

                      @Chris-Kawa is there a way to change the checkbox border and mark color so it doesn't look grayed outScreenshot_1.png

                      I have tried

                      QPalette p(Qt::black);
                      style()->polish(p);
                      
                      painter->setPen(Qt::black);
                      painter->setBrush(Qt::back);
                      
                      option.palette = QPalette(Qt::black);
                      

                      But none of the above worked.
                      Is there a way to change its color?

                      C Offline
                      C Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on 18 Jun 2021, 19:49 last edited by
                      #20

                      @hbatalha It's an image so changing pen, brush or palette doesn't affect it. It might appear disabled if you give it the wrong state flags when painting, so check that the state member is set correctly in the style option.
                      The checkbox also appears crooked in your screenshot, which suggests the rect member is set incorrectly, so again make sure you set all the members of your style options object correctly before painting with it.

                      H 1 Reply Last reply 18 Jun 2021, 20:31
                      1
                      • C Chris Kawa
                        18 Jun 2021, 19:49

                        @hbatalha It's an image so changing pen, brush or palette doesn't affect it. It might appear disabled if you give it the wrong state flags when painting, so check that the state member is set correctly in the style option.
                        The checkbox also appears crooked in your screenshot, which suggests the rect member is set incorrectly, so again make sure you set all the members of your style options object correctly before painting with it.

                        H Offline
                        H Offline
                        hbatalha
                        wrote on 18 Jun 2021, 20:31 last edited by hbatalha
                        #21

                        @Chris-Kawa said in Add a QCheckBox as a header to a QTableWidget:

                        so again make sure you set all the members of your style options object correctly before painting with it.

                        The code is like the one you provided in your answer above:

                        class CheckBox : public QHeaderView
                        {
                            Q_OBJECT
                        
                        public:
                            using QHeaderView::QHeaderView;
                        
                        signals:
                            void clicked(bool);
                        
                        protected:
                        
                            void paintSection(QPainter* painter, const QRect &rect, int logicalIndex) const override
                            {
                                painter->save();
                                QHeaderView::paintSection(painter, rect, logicalIndex);
                                painter->restore();
                        
                                if (model() && logicalIndex == 0)
                                {
                                    QStyleOptionButton option;
                                    option.initFrom(this);
                        
                                    QRect checkbox_rect = style()->subElementRect(QStyle::SubElement::SE_CheckBoxIndicator, &option, this);
                                    checkbox_rect.moveLeft(rect.left());
                        
                                    bool checked = model()->headerData(logicalIndex, orientation(), Qt::CheckStateRole).toBool();
                        
                                    option.rect = checkbox_rect;
                                    option.state = checked ? QStyle::State_On : QStyle::State_Off;
                        
                                    style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
                                }
                            }
                        
                        public:
                        
                            void mouseReleaseEvent(QMouseEvent* event) override
                            {
                                QHeaderView::mouseReleaseEvent(event);
                                if(model())
                                {
                                    int section = logicalIndexAt(event->pos());
                                    if (section >= 0)
                                    {
                                        bool checked = model()->headerData(section, orientation(), Qt::CheckStateRole).toBool();
                                        model()->setHeaderData(section, orientation(), !checked, Qt::CheckStateRole);
                                        viewport()->update();
                                        emit clicked( ! checked);
                                    }
                                }
                            }
                        };
                        

                        Edit: The problem is only on windows for the looks of it as I just tested it on linux mint 20.1 and it looks totally fine

                        1 Reply Last reply
                        0
                        • N Offline
                          N Offline
                          nonskill
                          wrote on 22 Jul 2022, 07:34 last edited by
                          #22

                          No one mentioned how to add Checkbox in QTableWidget header with PartiallyChecked support, anyone knowns how to make it? There only option for Checkbox is just QStyle::State_On and QStyle::State_Off, which is far from functional. The most important option QStyle::State_Partial is not found.

                          JonBJ 1 Reply Last reply 22 Jul 2022, 07:44
                          0
                          • N nonskill
                            22 Jul 2022, 07:34

                            No one mentioned how to add Checkbox in QTableWidget header with PartiallyChecked support, anyone knowns how to make it? There only option for Checkbox is just QStyle::State_On and QStyle::State_Off, which is far from functional. The most important option QStyle::State_Partial is not found.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on 22 Jul 2022, 07:44 last edited by JonB
                            #23

                            @nonskill
                            Did you try QStyle::State_NoChange ("Used to indicate a tri-state checkbox.") from flags QStyle::State?

                            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