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 Align Center Qtableview Checkbox
Forum Updated to NodeBB v4.3 + New Features

How to Align Center Qtableview Checkbox

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 3.3k Views 1 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.
  • D Offline
    D Offline
    DzCode
    wrote on last edited by
    #1

    Hi everyone

    In my model I am usign overriden flags() method and I am using ItemIsUserCheckable for the checkbox column of my custom tableview.

    However, everytime the checkbox is left-aligned. I cannot aligned it center or right.
    When I use margin-left and margin-right in 50% it does not work for this if the column width changes dynamically

    Is there any way to align them center without changing the my model class

    1 Reply Last reply
    1
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Searching for tableview checkbox center in the forum search gives you for example https://forum.qt.io/topic/94049/

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      D 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        Searching for tableview checkbox center in the forum search gives you for example https://forum.qt.io/topic/94049/

        D Offline
        D Offline
        DzCode
        wrote on last edited by DzCode
        #3

        @Christian-Ehrlicher I looked at this topic 2 days ago. And it does not work

        JonBJ Christian EhrlicherC 3 Replies Last reply
        0
        • D DzCode

          @Christian-Ehrlicher I looked at this topic 2 days ago. And it does not work

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @DzCode
          By complete coincidence, I am about to want just this later today/tomorrow! I'll let you know how I get on, and of course keep an eye on this thread.

          1 Reply Last reply
          0
          • D DzCode

            @Christian-Ehrlicher I looked at this topic 2 days ago. And it does not work

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @DzCode said in How to Align Center Qtableview Checkbox:

            And it does not work

            That's no problem description. Please show us your class derived from QStyledItemDelegate

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            JonBJ 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              @DzCode said in How to Align Center Qtableview Checkbox:

              And it does not work

              That's no problem description. Please show us your class derived from QStyledItemDelegate

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Christian-Ehrlicher
              Hi Christian/whoever. I am now ready to try out the code(s) offered in https://forum.qt.io/topic/94049/.

              Like @DzCode, my QTableView column items have Qt::ItemIsUserCheckable, and I have the code working for Qt::CheckStateRole. I just need to move the box from the left to the center.

              But I am unsure how to proceed. I am familiar with QStyledItemDelegate, and the table already has a custom one which tests for column and does certain things on certain columns. It would be easy to add a case for the centered checkbox column, and that is what I'd like to do.

              But when I look at the code there it does stuff via class CenteredBoxProxy : public QProxyStyle. I'm afraid I am not familiar with how that works. I realize I could try it out. But you did say "Please show us your class derived from QStyledItemDelegate", and that's how I would like to do it. I do not want/need the CheckAlignmentRole and the index.data(CheckAlignmentRole) to store/fetch the alignment setting from the model.

              So... can I take the code shown there in CenteredBoxProxy::subElementRect() and put it directly into somewhere inside my QStyledItemDelegate instead? How/where?

              For example (and only as example), I see that old post from 2010 https://www.qtcentre.org/threads/29668-How-to-centering-the-checkbox-in-qtableview is doing stuff in TestDelegate::paint() --- but it is doing its own checkbox against the data, I like Qt::ItemIsUserCheckable which means Qt is handling the checkbox so I don't think that approach is right in that case?

              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by Christian Ehrlicher
                #7

                It depends on what you want to do - if you just want to paint the checkbox in the middle without user interaction I would go for a QStyledItemDelegate similar to

                void paint(QPainter *painter,
                           const QStyleOptionViewItem &option, const QModelIndex &index) const override
                {
                
                  QStyleOptionViewItem opt = option;
                  initStyleOption(&opt, index);
                
                  QStyle *style = option.widget ? option.widget->style() : QApplication::style();
                  style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, option.widget);
                  switch (option.checkState) {
                  case Qt::Unchecked:
                      opt.state |= QStyle::State_Off;
                      break;
                  case Qt::PartiallyChecked:
                      opt.state |= QStyle::State_NoChange;
                      break;
                  case Qt::Checked:
                      opt.state |= QStyle::State_On;
                      break;
                  }
                  opt.state = opt.state & ~QStyle::State_HasFocus;
                  auto rect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, option.widget);
                  opt.rect = QStyle::alignedRect(option.direction, Qt::AlignVCenter | Qt::AlignHCenter, rect.size(), opt.rect);
                
                  painter->save();
                  painter->setClipRect(opt.rect);
                  style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, option.widget);
                  painter->restore();
                }
                

                But when you need user interaction the click you have to go with a QProxyStyle since the subElementRect is used for click detection. So @VRonin's solution is the way to go for you.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                JonBJ 1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  It depends on what you want to do - if you just want to paint the checkbox in the middle without user interaction I would go for a QStyledItemDelegate similar to

                  void paint(QPainter *painter,
                             const QStyleOptionViewItem &option, const QModelIndex &index) const override
                  {
                  
                    QStyleOptionViewItem opt = option;
                    initStyleOption(&opt, index);
                  
                    QStyle *style = option.widget ? option.widget->style() : QApplication::style();
                    style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, option.widget);
                    switch (option.checkState) {
                    case Qt::Unchecked:
                        opt.state |= QStyle::State_Off;
                        break;
                    case Qt::PartiallyChecked:
                        opt.state |= QStyle::State_NoChange;
                        break;
                    case Qt::Checked:
                        opt.state |= QStyle::State_On;
                        break;
                    }
                    opt.state = opt.state & ~QStyle::State_HasFocus;
                    auto rect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, option.widget);
                    opt.rect = QStyle::alignedRect(option.direction, Qt::AlignVCenter | Qt::AlignHCenter, rect.size(), opt.rect);
                  
                    painter->save();
                    painter->setClipRect(opt.rect);
                    style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, option.widget);
                    painter->restore();
                  }
                  

                  But when you need user interaction the click you have to go with a QProxyStyle since the subElementRect is used for click detection. So @VRonin's solution is the way to go for you.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @Christian-Ehrlicher
                  Hi, thanks.

                  As I said, to be 100% percent clear. I am setting Qt::ItemIsUserCheckable because... it has to be checkable by user! I take that to mean "interactive" --- I don't only show the checkbox, I need user to be avle to click it exactly as he can right now. Only it's at the left and I want it moved to the middle....

                  So, from that I take it I must indeed follow @VRonin , and that other @Robert-Hairgrove, in that post.

                  What I do not get is the connection between: they define a class CenteredBoxProxy : public QProxyStyle class, but the only thing they do with it is app.setStyle(new CenteredBoxProxy);.

                  • I don't get how whatever knows to "execute" this style against by QTableView which happens to have Qt::ItemIsUserCheckable in some items' flags. Where is the connection?

                  • And earlier you said, when that guy claimed @VRonin code "does not work", "Please show us your class derived from QStyledItemDelegate". So now if I'm using a CenteredBoxProxy, where is any connection from that to my QStyledItemDelegate?

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by Christian Ehrlicher
                    #9

                    @JonB said in How to Align Center Qtableview Checkbox:

                    Where is the connection?

                    The connection is how QProxyStyle works. When you take a look at qcommonproxy.cpp you will see that every call goes through proxy() which calls the proxy style implementation (if there is one). This means that everyone who calls QStyle::drawControl(CE_ItemViewItem, ...) will call your implementation.

                    /edit: Had some time to dig into the problem: https://bugreports.qt.io/browse/QTBUG-88978

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    1
                    • D DzCode

                      @Christian-Ehrlicher I looked at this topic 2 days ago. And it does not work

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #10

                      @DzCode said in How to Align Center Qtableview Checkbox:

                      @Christian-Ehrlicher I looked at this topic 2 days ago. And it does not work

                      I can now confirm that I have deployed @VRonin's code given in https://forum.qt.io/topic/94049/how-to-center-a-column-with-a-checkbox-in-qtableview/8, and it works correctly :) You did do the app.setStyle(new CenteredBoxProxy); he shows, and you did make your model's data(index, CheckAlignmentRole) so that returns Qt::AlignHCenter, didn't you?

                      [I didn't make @Robert-Hairgrove's modifications for "focus rectangle" per https://forum.qt.io/topic/94049/how-to-center-a-column-with-a-checkbox-in-qtableview/12, because TBH I couldn't see any focus rectangle anyway (Ubuntu, GNOME)!]

                      1 Reply Last reply
                      0
                      • L Offline
                        L Offline
                        lynnepv
                        wrote on last edited by
                        #11

                        I had this issue for several years, and have read everything posted on centering a checkbox. This solution is the only one that works "perfectly". My post is for adding a focus rectangle on [TAB] keyboard focus of the centered checkbox. You'll have to read this post thoroughly for complete code, but here is the summary:

                        1. Make a derived style based on QProxyStyle. The code is below in this post. Add this code to the "elements" list:
                          if (element == SE_ItemViewItemText) {
                          retval = itemRect;
                          }
                        2. Include the headerfile at the application.h level and use setStyle( new CenteredBoxProxy ); in the application. I didn't know that a QProxyStyle gets interrogated first in the processing hierarchy for application to drawing. I spent a great deal of time trying it in ItemDelegate.
                        3. In the subclassed StyleItemDelegate createEditor function use a styleSheet on the returned editor widget.

                        QWidget* pvItemDelegate::createEditor(QWidget parent,
                        const QStyleOptionViewItem &option,
                        const QModelIndex &index) const
                        {
                        QStandardItem
                        column = index.model()->itemFromIndex(index);
                        if (column->isCheckable())
                        {
                        QWidget* w = new QWidget(parent);
                        w->setStyleSheet(QString("border-width: 1px; border-style: solid; border-color: darkblue;"));
                        return w;
                        }

                        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