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. [Solved] Painting in custom delegate
QtWS25 Last Chance

[Solved] Painting in custom delegate

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 5.2k Views
  • 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.
  • R Offline
    R Offline
    rovshanb
    wrote on last edited by
    #1

    Hi, I've created a custom delegate for use in in a class derived from QTableView. This delagate must display as a checkbox centered horizontally and vertically in table cell. I've managed to implement createEditor, setEditorData, setModelData and updateEditorGeometry methods correctly. Now I'm trying to implement the paint method. Below is my code:

    @void BooleanDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
    QVariant value=index.data();
    if (!value.isValid() || qVariantCanConvert<bool>(value)) {
    bool boolVal = value.isValid() ? value.toBool() : defaultValue;

        QStyle *style=qApp->style();
    
        QStyleOptionViewItem modifiedOption(option);
    
        QRect checkBoxRect=style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
        int centerX=option.rect.left() + qMax(option.rect.width()/2-checkBoxRect.width()/2, 0);
        int centerY=option.rect.top() + qMax(option.rect.height()/2-checkBoxRect.height()/2, 0);
        modifiedOption.rect.moveTo(centerX, centerY);
    
        if(boolVal){
            modifiedOption.state |= QStyle::State_On;
        }
    
        style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &modifiedOption, painter);
    }else {
        QStyledItemDelegate::paint(painter, option, index);
    }
    

    }
    @
    On Linux this code works fine, also on Windows XP and Windows 7 with classic style everything is OK.But when I switch to modern styles (on Windows XP and 7) checkbox gets rendered at the bottom right corner of the table cell. On the other hand if I comment out these lines:

    @QRect checkBoxRect=style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
    int centerX=option.rect.left() + qMax(option.rect.width()/2-checkBoxRect.width()/2, 0);
    int centerY=option.rect.top() + qMax(option.rect.height()/2-checkBoxRect.height()/2, 0);
    modifiedOption.rect.moveTo(centerX, centerY);@

    then checkbox gets rendered at the top left corner of the cell in Linux and Windows classic styles (and at the center on Windows modern styles). I tried setting modifiedOption.decorationAlignment and displayAlignment to Qt::AlignHCenter | Qt::AlignVCenter but it did not help.

    How should I fix it? I want checkbox to be displayed at the center all the time.

    Thanks in advance!

    1 Reply Last reply
    0
    • R Offline
      R Offline
      rovshanb
      wrote on last edited by
      #2

      I think I found solution:

      @void BooleanDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
      const QModelIndex &index) const
      {
      QVariant value=index.data();
      if (!value.isValid() || qVariantCanConvert<bool>(value)) {
      bool boolVal = value.isValid() ? value.toBool() : defaultValue;

          QStyle *style=qApp->style();
      
          QRect checkBoxRect=style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
          int chkWidth=checkBoxRect.width();
          int chkHeight=checkBoxRect.height();
      
          QStyleOptionViewItem modifiedOption(option);
          modifiedOption.rect.moveTo(0, 0);
          modifiedOption.rect.setSize(QSize(chkWidth, chkHeight));
          if(boolVal){
              modifiedOption.state |= QStyle::State_On;
          }
      
          QPixmap checkboxPixmap(chkWidth, chkHeight);
          QPainter pixmapPainter(&checkboxPixmap);
          pixmapPainter.fillRect(0, 0, chkWidth, chkHeight, index.row()%2==0 ? qApp->palette().base() : qApp->palette().alternateBase());
          style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &modifiedOption, &pixmapPainter);
      
          int centerX=option.rect.left() + qMax(option.rect.width()/2-chkWidth/2, 0);
          int centerY=option.rect.top() + qMax(option.rect.height()/2-chkHeight/2, 0);
      
          painter->drawPixmap(centerX, centerY, chkWidth, chkHeight, checkboxPixmap);
      }else {
          QStyledItemDelegate::paint(painter, option, index);
      }
      

      }@

      This seems to work in all scenarios.

      1 Reply Last reply
      0
      • R Offline
        R Offline
        rovshanb
        wrote on last edited by
        #3

        Final version (just in case it will be useful to someone else):

        @void BooleanDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
        const QModelIndex &index) const
        {
        QVariant value=index.data();
        if (!value.isValid() || qVariantCanConvert<bool>(value)) {
        bool boolVal = value.isValid() ? value.toBool() : defaultValue;

            QStyle *style=qApp->style();
        
            QRect checkBoxRect=style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
            int chkWidth=checkBoxRect.width();
            int chkHeight=checkBoxRect.height();
        
            int centerX=option.rect.left() + qMax(option.rect.width()/2-chkWidth/2, 0);
            int centerY=option.rect.top() + qMax(option.rect.height()/2-chkHeight/2, 0);
            QStyleOptionViewItem modifiedOption(option);
            modifiedOption.rect.moveTo(centerX, centerY);
            modifiedOption.rect.setSize(QSize(chkWidth, chkHeight));
            if(boolVal){
                modifiedOption.state |= QStyle::State_On;
            }
        
            style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &modifiedOption, painter);
        }else {
            QStyledItemDelegate::paint(painter, option, index);
        }
        

        }@

        1 Reply Last reply
        0
        • P Offline
          P Offline
          p91paul
          wrote on last edited by
          #4

          this post is old, but not too much to say thank you! :D

          1 Reply Last reply
          0
          • JonBJ JonB referenced this topic on

          • Login

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