QTableView checkbox center with stylesheet
Hi!
I tried to center the checkbox in QTableView by something like this:
Code:
qApp->setStyleSheet("::indicator {subcontrol-position: center; subcontrol-origin: padding;}");
But it doesn't work for QTableView item (set by Qt::CheckStateRole in model), although it works good for any other usual widget like QCheckBox or QRadioButton.
Is that bug in Qt or maybe Qt just does't provide this stylesheet subcontrol feature for item views?
I see that other properties like e.g 'left' also work for checkbox indicator in view.
Re: QTableView checkbox center with stylesheet
Hi,
almost a year since you posted this issue. Did you find a solution? I have the exact problem and it would be really nice if I could solve it using stylesheets. I haven't found a way to solve it in the model-view-delegate either, it is really annoying with the left-aligned checkboxes in my treeviews and tableviews.
Re: QTableView checkbox center with stylesheet
Hi,
If this is still actual here is how I managed to put checkboxes at the center:
1) Create widget class:
Code:
#ifndef CENTEREDCHECKBOXWIDGET_H
#define CENTEREDCHECKBOXWIDGET_H
#include <QWidget>
class CenteredCheckBoxWidget
: public QWidget{
Q_OBJECT
public:
explicit CenteredCheckBoxWidget
(QWidget *parent
= 0);
private:
};
#endif // CENTEREDCHECKBOXWIDGET_H
#include "centeredcheckboxwidget.h"
#include <QtGui>
CenteredCheckBoxWidget
::CenteredCheckBoxWidget(QWidget *parent
) :{
setContentsMargins(0, 0, 0, 0);
setAutoFillBackground(true);
layout->addWidget(checkbox);
layout->setAlignment(checkbox, Qt::AlignHCenter | Qt::AlignVCenter);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
setLayout(layout);
setFocusProxy(checkbox);
}
QCheckBox *CenteredCheckBoxWidget
::checkBox() const {
return checkbox;
}
2) Create custom delegate:
Code:
#ifndef BOOLEANDELEGATE_H
#define BOOLEANDELEGATE_H
#include <QStyledItemDelegate>
class BooleanDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit BooleanDelegate
(QObject *parent,
bool defaultValue
=true);
void updateEditorGeometry
(QWidget *editor,
private:
bool defaultValue;
};
#endif // BOOLEANDELEGATE_H
#include "booleandelegate.h"
#include "widgets/centeredcheckboxwidget.h"
#include <QtGui>
BooleanDelegate
::BooleanDelegate(QObject *parent,
bool defaultValue
) : QStyledItemDelegate(parent), defaultValue(defaultValue)
{
}
{
if (!value.isValid() || qVariantCanConvert<bool>(value)) {
bool boolVal = value.isValid() ? value.toBool() : defaultValue;
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);
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);
}
}
{
CenteredCheckBoxWidget *editor=new CenteredCheckBoxWidget(parent);
editor->checkBox()->setChecked(defaultValue);
return editor;
}
void BooleanDelegate
::setEditorData(QWidget *editor,
{
QVariant data
=index.
model()->data
(index, Qt
::EditRole);
bool value;
if(!data.isNull()){
value=data.toBool();
}else{
value=defaultValue;
}
CenteredCheckBoxWidget *checkBoxWidget = static_cast<CenteredCheckBoxWidget*>(editor);
checkBoxWidget->checkBox()->setChecked(value);
}
{
CenteredCheckBoxWidget *checkBoxWidget = static_cast<CenteredCheckBoxWidget*>(editor);
bool value = checkBoxWidget->checkBox()->isChecked();
model->setData(index, value, Qt::EditRole);
}
void BooleanDelegate
::updateEditorGeometry(QWidget *editor,
{
CenteredCheckBoxWidget *checkBoxWidget = static_cast<CenteredCheckBoxWidget*>(editor);
QSize size
=checkBoxWidget
->sizeHint
();
editor->setMinimumHeight(size.height());
editor->setMinimumWidth(size.width());
editor->setGeometry(option.rect);
}
3) Set the above delegate for the column:
Code:
BooleanDelegate *isNullableDelegate=new BooleanDelegate(this);
table->setItemDelegateForColumn(columnIndex, isNullableDelegate);
When retrieving data for this cell use Qt::EditRole and cast it to boolean
Code:
QVariant nullable
=model
->index
(rowIndex, columnIndex
).
data(Qt
::EditRole);
bool isNullable=nullable.isValid() ? nullable.toBool() : defaultValue; //replace defaultValue with true or false depending on your scenario
Hope this is useful.