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. Wrong selection background in custom QItemDelegate
Forum Updated to NodeBB v4.3 + New Features

Wrong selection background in custom QItemDelegate

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

    I try to create checkable checkbox item for QTableView. But default methods involve the use of QAbstractItemView::AllEditTriggers, but I'm use QAbstractItemView::NoEditTriggers, because table have to be uneditable for user, except of checkboxes.

    So I inherits QItemDelegate. And here is how it looks:
    !http://storage7.static.itmages.ru/i/12/0807/h_1344366097_7345772_5f64de37d4.png(example)!
    @void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    drawBackground(painter, option, index);
    drawFocus(painter, option, option.rect);
    QStyleOptionViewItemV4 opt(option);
    opt.rect = checkRect(option, option.rect);
    opt.state = opt.state & ~QStyle::State_HasFocus;
    opt.state |= (index.data().toInt() > 0 ? QStyle::State_On : QStyle::State_Off);
    qApp->style()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter);
    }@

    And here you can see a problem. On KDE (Linux) selection background are flat. But have to be volumed, like default (see "Total" column).

    How can I make it look normal?

    PS: I try to use QStyledItemDelegate, but selection simply disappear...
    @void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    const QModelIndex &index) const
    {
    QStyleOptionViewItemV4 opt(option);
    initStyleOption(&opt, index);

    QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
    opt.rect = checkRect(option, option.rect);
    opt.state = opt.state & ~QStyle::State_HasFocus;
    opt.state |= (index.data().toInt() > 0 ? QStyle::State_On : QStyle::State_Off);
    style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter);
    

    }@

    1 Reply Last reply
    0
    • JeroentjehomeJ Offline
      JeroentjehomeJ Offline
      Jeroentjehome
      wrote on last edited by
      #2

      Hi there,
      A checkbox is one of the widgets that you do not need a separate delegate for if using qstandardItem. The "checked state" in the QStandardModel is available for it.
      Otherwise keep searching for the proper option that does it.
      good luck

      Greetz, Jeroen

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

        As I say, if I use:
        @this->model()->setData(model()->index(0, 0, Qt::Checked, Qt::CheckStateRole);@
        with QAbstractItemView::NoEditTriggers - I can't click on it.

        PS: also it looks wierd:
        !http://storage7.static.itmages.ru/i/12/0808/h_1344423289_5346095_17f286dad8.png(example)!

        1 Reply Last reply
        0
        • JeroentjehomeJ Offline
          JeroentjehomeJ Offline
          Jeroentjehome
          wrote on last edited by
          #4

          The 0 you can remove by returning an empty string in the model::data(). Don't have my project at hand, but you are able to center the checkbox in the model AFAIK. When you have the NoEditTriggers you can't trigger anything, so even when you use a delegate it shouldn't be called from the view when selected. Or does it?
          Good luck finding the solution.

          Greetz, Jeroen

          1 Reply Last reply
          0
          • R Offline
            R Offline
            RazrFalcon
            wrote on last edited by
            #5

            I know, but my delegate is clickable with NoEditTriggers.

            Here is the source (finded somewhere in the internet):
            @
            #ifndef CHBOXDELEGATE_H
            #define CHBOXDELEGATE_H

            #include <QtGui/QItemDelegate>

            class CheckBoxDelegate : public QItemDelegate
            {
            Q_OBJECT

            public:
            explicit CheckBoxDelegate(bool eventEnabled, QObject* parent = 0);
            QRect checkRect(const QStyleOptionViewItem &option, const QRect &bounding) const;

            private:
            bool isEventEnabled;
            QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
            const QModelIndex& index ) const;
            void paint(QPainter* painter, const QStyleOptionViewItem& option,
            const QModelIndex& index) const;
            bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option,
            const QModelIndex& index);
            };

            #endif // CHBOXDELEGATE_H

            #include <QtGui/QApplication>
            #include <QtGui/QMouseEvent>
            #include <QtGui/QPainter>

            #include "chboxdelegate.h"

            CheckBoxDelegate::CheckBoxDelegate(bool eventEnabled, QObject *parent) :
            QItemDelegate(parent)
            {
            isEventEnabled = eventEnabled;
            }

            QWidget* CheckBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
            const QModelIndex &index) const
            {
            Q_UNUSED (parent)
            Q_UNUSED (option)
            Q_UNUSED (index)
            return NULL;
            }

            // FIXME: wrong background on KDE
            void CheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
            const QModelIndex &index) const
            {
            drawBackground(painter, option, index);
            drawFocus(painter, option, option.rect);
            QStyleOptionViewItemV4 opt(option);
            opt.rect = checkRect(option, option.rect);
            opt.state = opt.state & ~QStyle::State_HasFocus;
            opt.state |= (index.data().toInt() > 0 ? QStyle::State_On : QStyle::State_Off);
            qApp->style()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter);

            }

            QRect CheckBoxDelegate::checkRect(const QStyleOptionViewItem &option, const QRect &bounding) const
            {
            QStyleOptionButton opt;
            opt.QStyleOption::operator=(option);
            opt.rect = bounding;
            QRect cr = qApp->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt);
            int deltaX = (bounding.width()-cr.width())/2;
            int deltaY = (bounding.height()-cr.height())/2;
            return QRect(bounding.left() + deltaX, bounding.top() + deltaY, cr.width(), cr.height());
            }

            bool CheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
            const QStyleOptionViewItem &option, const QModelIndex &index)
            {
            if (!isEventEnabled)
            return false;

            if(!event || !model)
                return false;
            
            Qt::ItemFlags flags = model->flags(index);
            if (!(option.state & QStyle::State_Enabled) || !(flags & Qt::ItemIsEnabled))
                return false;
            
            
            switch(event->type()) {
            case QEvent::MouseButtonRelease :
            case QEvent::MouseButtonDblClick : {
                QRect cr(checkRect(option, option.rect));
                QMouseEvent *me = static_cast<QMouseEvent*>(event);
                if (me->button() != Qt::LeftButton || !cr.contains(me->pos()))
                    return false;
            
                // eat the double click events inside the check rect
                if(event->type() == QEvent::MouseButtonDblClick)
                    return true;
                break;
            }
            case QEvent::KeyPress : {
                QKeyEvent *kev = static_cast<QKeyEvent*>(event);
                if(kev->key() != Qt::Key_Space && kev->key() != Qt::Key_Select)
                    return false;
                break;
            }
            default: return false;
            }
            
            
            int value = (index.data().toInt() == 0 ? 2 : 0);
            return model->setData(index, value, Qt::EditRole);
            

            }
            @

            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