Eurydice
Eurydice

Reputation: 8449

QTableView and QAbstractTableModel with customized checkbox buttons

I am using qt5 (5.5.1) to derive QTableView widget filled through a QAbstractTableModel for which I would like some columns (e.g. the 3rd one) to contain QCheckBox widgets. I would like those QCheckBox widgets to be customized with two icons: a red sphere for the false state and a green sphere for the true state instead of the standard QCheckBox appearance. So far so good, I could do this using a custom delegate with the following implementation:

MyDelegate.cpp

#include "mydelegate.h"
#include <QCheckBox>
#include <QPainter>
#include <QKeyEvent>

#include <QtDebug>
#include <QApplication>
#include <QStyleOptionViewItem>

MyDelegate::MyDelegate(QObject *parent) :
    QStyledItemDelegate(parent)
{
   // The green sphere
    _icon.addPixmap(QPixmap(":/selected.png"), QIcon::Normal, QIcon::On);
   // The red sphere
    _icon.addPixmap(QPixmap(":/deselected.png"), QIcon::Normal, QIcon::Off);
}

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.column() != 2)
        QStyledItemDelegate::paint(painter,option,index);
    else
    {
        bool value  = index.model()->data(index,Qt::UserRole).toBool();
        QStyleOptionButton buttonVis;
        buttonVis.rect = option.rect;
        buttonVis.iconSize = QSize(15,15);
        buttonVis.icon = _icon;
        buttonVis.features |= QStyleOptionButton::Flat;
        buttonVis.state |= QStyle::State_Enabled;
        buttonVis.state |= value ? QStyle::State_On : QStyle::State_Off;
        QApplication::style()->drawControl(QStyle::CE_PushButton,&buttonVis,painter);
    }
}

bool MyDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if(event->type() == QEvent::MouseButtonRelease)
    {
        bool value  = model->data(index,Qt::UserRole).toBool();
        model->setData(index, !value, Qt::UserRole);
    }
    return true;
}

Unfortunately when I click on one of the checkbox the on state green icon appears as a raised push-button. The off state red icon is OK. (see pictures below). Would you see how to change my code in order that this button always stays flat whatever its state ? Thanks

off state on state

Upvotes: 0

Views: 1488

Answers (1)

frbaresi
frbaresi

Reputation: 96

Seems to be an issue related with "Flat" property. If you're able to change the Icon properties, you can use the solution below:

Use:

// The green sphere
_icon.addPixmap(QPixmap(":/selected.png"), QIcon::Normal, QIcon::On);
// The red sphere
_icon.addPixmap(QPixmap(":/deselected.png"), QIcon::Disabled, QIcon::On);

instead of:

// The green sphere
_icon.addPixmap(QPixmap(":/selected.png"), QIcon::Normal, QIcon::On);
// The red sphere
_icon.addPixmap(QPixmap(":/deselected.png"), QIcon::Normal, QIcon::Off);

and use:

buttonVis.state |= value ? QStyle::State_Enabled : QStyle::State_None;

instead of:

buttonVis.state |= QStyle::State_Enabled;
buttonVis.state |= value ? QStyle::State_On : QStyle::State_Off;

Upvotes: 2

Related Questions