I have a custom Delegate
class which inherits from QStyledItemDelegate
. In its paint()
event, I would like to add QStyleOptionButton
which should be checkable. Is it possible?
For example, it denotes visibility property with an icon of eye; and when the button is pressed, the eye icon turns into closed-eye icon.
Inside the paint()
method, this is my current code to create the button:
QStyleOptionButton buttonVis;
buttonVis.rect = getButtonVisibilityRect();
buttonVis.iconSize = QSize(sizeX, sizeY);
buttonVis.icon = icon;
buttonVis.state = QStyle::State_Enabled;
buttonVis.features = QStyleOptionButton::None;
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonVis, painter);
The icon that I load to the buttonVis
is created by:
QIcon icon;
icon.addPixmap(QPixmap(":/control-visibility.svg"), QIcon::Normal, QIcon::On);
icon.addPixmap(QPixmap(":/control-visibilityNo.svg"), QIcon::Normal, QIcon::Off);
For the moment when I run my program, the button has an icon with closed eye. Is there a command to control which icon is displayed? If my initial layout is not possible to implement, what is the right direction to go?
EDIT: I found out how to select which icon to use in order to simulate the checkbox look. Instead if line buttonVis.state = QStyle::State_Enabled;
there should be:
if (/* current item checkbox checked? */)
buttonVis.state = QStyle::State_Enabled | QStyle::State_On;
else
buttonVis.state = QStyle::State_Enabled | QStyle::State_Off;
The problem now is to figure out what is that condition or how to set it up from the editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
. The problem is that I cannot really change option
by myself since it is constant reference. Any ideas how to do it, or how to get around it?
Finally, I figured out how to set up certain flag and then test for it and see if the button changed an icon.
So, for the icon change, as I mentioned on the edit of my question, I have to use something like:
buttonVis.state |= QStyle::State_Enabled;
buttonVis.state |= isChanged? QStyle::State_Off : QStyle::State_On;
So it comes down on how to set up isChanged
flag. And it can be done within editorEvent()
method of the delegate:
bool Delegate::editorEvent(QEvent *event, QAbstractItemModel *model, const StyleOptionViewItem &option, const QModelIndex &index)
{
if (/* event is release and it is over the button area*/)
{
bool value = index.data(Qt::UserRole).toBool();
// this is how we setup the condition flag
model->setData(index, !value, Qt::UserRole);
return true;
}
}
Now to use the setup flag, we do it in the paint()
event right before we set up buttonVis.state
:
bool isChanged = index.data(Qt::UserRole).toBool();
By adding these steps my QStyleOptionButton
is now behaving like a checkbox, but it changes icons as states.