PDA

View Full Version : Get checkbox of QStandardItem



Neptilo
2nd December 2014, 02:01
I have a custom QComboBox using a model in which I set some QStandardItems. I made these items checkable:
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);

The problem is when I deploy my app for Android, the checkboxes are so small I cannot even click on them. That's why I would like to set a style for them, so my question is: how do I get the checkbox objects of a QStandardItem so I can call QWidget::setStyle() on them?

Additional issue to be taken into account: the checkboxes do not always show up depending on the OS, so I'm using one of these workarounds:


set another style for my QComboBox, which will display the checkboxes correctly
set a custom QStyledItemDelegate with a redefined QStyledItemDelegate::paint() method, as suggested in a Stackoverflow thread

wysota
2nd December 2014, 07:18
There are no checkbox objects. The boxes are drawn by a delegate, so the easiest approach is to provide a custom delegate that will draw the boxes the way you want.

Neptilo
2nd December 2014, 10:04
Thanks for your answer.

Ok then how do I find which image file Qt was using before, so I can paint it again in a bigger size? Looking into the source of QStyledItemDelegate did not provide any information about that.

How can I paint an image in a delegate? The QStyledItemDelegate doc does not seem to cover painting images.

And most importantly, how do I tell Qt that the painted image is the actual checkbox (so when I click it the item changes the value of its Qt::CheckStateRole)?

wysota
2nd December 2014, 11:26
Have a look at QStylePainter. Regarding the second question, the delegate handles events for items in editorEvent() method, you have to implement a hit test there and update the model if you hit the checkbox.

Neptilo
2nd December 2014, 12:42
Thanks. I'm playing around with QStylePainter right now. I'll let you know if I get to achieve what I want.

wysota
2nd December 2014, 13:23
What you want is probably drawControl() and QStyle::CE_CheckBox.

Neptilo
2nd December 2014, 13:42
So how to use these?

I'm not sure but I suspect this will paint the default icons in their default size, so much too small in the case of Android. Or are you thinking of a way to resize them?

Anyway I'm experimenting with the advice in your previous post now and I feel like it will do fine. :)

Neptilo
2nd December 2014, 17:26
I managed to get by with the paint() method, but I'm kinda stuck with editorEvent(). Edit: I had a look at QItemDelegate source and found how to do it:


bool CheckableItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
Q_UNUSED(option);
if (event->type() == QEvent::MouseButtonRelease) {
QVariant value = index.data(Qt::CheckStateRole);
Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
? Qt::Unchecked : Qt::Checked);
return model->setData(index, state, Qt::CheckStateRole);
} else
return false;
}


This will intercept all mouse clicks on the item (and I'm ok with it).

Neptilo
7th December 2014, 05:52
Update:

I think I nailed it, hinted by this post (http://www.informit.com/articles/article.aspx?p=1405556&seqNum=2).

So I subclassed QProxyStyle as AndroidStyle and reimplemented QProxyStyle::pixelMetric this way:



int AndroidStyle::pixelMetric(PixelMetric which,
const QStyleOption *option,
const QWidget *widget) const
{
int metric = QProxyStyle::pixelMetric(which, option, widget);
switch (which) {
case PM_IndicatorWidth:
case PM_IndicatorHeight:
return 2*metric;
default:
return metric;
}
}


and I set this style in the main function like this:


QApplication a(argc, argv);
a.setStyle(new AndroidStyle);