PDA

View Full Version : Painting QCheckbox into QTableView



GimpMaster
18th May 2010, 15:29
Hello, I believe I have read through most of the posts on QCheckbox's and QTableviews. It seems most people prefer to use a custom delegate which makes sense. I have used the spinboxdelegate as an example and I was successful in getting the QCheckbox to draw when entering the editrole of the table view, however when not in the edit role (i.e. paint()) function I have not yet figured out how to successfully draw/render the QCheckbox. Here are my two questions with code to follow:

1. How can i make it so that a single click will toggle the checkbox as one would expect, instead of a double click to start editing and then a third click to toggle the checkbox?

2. What am I doing wrong in my paint function?

Thanks in advance!



void cCheckboxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
bool Checked = index.model()->data(index, Qt::EditRole).toBool();
QCheckBox CheckBox;
CheckBox.setChecked(Checked);
CheckBox.render(painter);
}

QSize cCheckboxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QCheckBox CheckBox;
return CheckBox.sizeHint();
}

QWidget *cCheckboxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QCheckBox *editor = new QCheckBox(parent);
return editor;
}

void cCheckboxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
bool checked = index.model()->data(index, Qt::EditRole).toBool();

QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
checkBox->setChecked(checked);
}

void cCheckboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
bool checked = checkBox->isChecked();

model->setData(index, checked, Qt::EditRole);
}

void cCheckboxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}

GimpMaster
18th May 2010, 17:52
Ok I got it to display the checkbox using the following code. However like I mentioned previous how would i make it so you don't have to triple click the checkbox to change the state?

Thanks



void cCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionButton BtnStyle;
BtnStyle.state = QStyle::State_Enabled;
if(index.model()->data(index, Qt::DisplayRole).toBool() == true)
BtnStyle.state |= QStyle::State_On;
else
BtnStyle.state |= QStyle::State_Off;
BtnStyle.direction = QApplication::layoutDirection();
BtnStyle.rect = option.rect;
QApplication::style()->drawControl(QStyle::CE_CheckBox,&BtnStyle,painter);
}

norobro
19th May 2010, 02:03
Are you aware of QStandardItem::setCheckable() (http://http://doc.qt.nokia.com/4.6/qstandarditem.html#setCheckable) ?

GimpMaster
19th May 2010, 16:09
Yes however I'm not using the StandItem, I'm subclassing QAbstractTableModel.

Anyways I think I found the best solution as far as user interface goes. If I edit my Model and set the flag to Qt::ItemIsUserCheckable and then respond to the Qt::CheckStateRole in the setData and data() functions the checkbox works as expected. I.E. you don't have to first double click into the cell before the editor widget pops up, you simply just click the checkbox and your done.

Here is some good sample code I used

http://www.qtcentre.org/threads/29655-Why-does-the-table-cell-containing-checkbox-becomes-solid-when-it-is-clicked?highlight=ItemIsUserCheckable