I have been re-writing this project from the bottom up to "correctly" use the Model/View framework. I have a database with several tables. I have set up two views in a QMainWindow, along with a QSqlTableModel for each table I need, and when I need, I just swap a view to a different model and reconfigure columns, etc. That is all working out nicely. I have also managed to subclass QStyledItem to create a combobox to present a list of text entries, display the chosen text entry in the cell, but store its corresponding "id" number in the backend table/database.
I am now attempting to set up some columns with QCheckBox for boolean values, and I am close, but not quite there.
Here's what I have.
cbitemdelegate.h
#ifndef CBITEMDELEGATE_H
#define CBITEMDELEGATE_H
#include <QItemDelegate>
{
Q_OBJECT
public:
explicit CBItemDelegate
(QObject *parent
= 0);
void setEditorData
(QWidget *editor,
void updateEditorGeometry
(QWidget *editor,
};
#endif //CBITEMDELEGATE_H
#ifndef CBITEMDELEGATE_H
#define CBITEMDELEGATE_H
#include <QItemDelegate>
class CBItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit CBItemDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void setEditorData(QWidget *editor,
const QModelIndex &index) const;
void setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
#endif //CBITEMDELEGATE_H
To copy to clipboard, switch view to plain text mode
cbitemdelegate.cpp
#include "cbitemdelegate.h"
#include <QApplication>
#include <QtGui>
CBItemDelegate
::CBItemDelegate(QObject *parent
){
}
editor->installEventFilter(const_cast<CBItemDelegate*>(this));
return editor;
}
void CBItemDelegate
::setEditorData(QWidget *editor,
int value = index.model()->data(index, Qt::DisplayRole).toInt();
QCheckBox *checkBox
= static_cast<QCheckBox
*>
(editor
);
if(value == 1)
checkBox->setCheckState(Qt::Checked);
else
checkBox->setCheckState(Qt::Unchecked);
}
void CBItemDelegate
::setModelData(QWidget *editor,
QCheckBox *checkBox
= static_cast<QCheckBox
*>
(editor
);
int value;
if(checkBox->checkState() == Qt::Checked)
value = 1;
else
value = 0;
model->setData(index, value);
}
void CBItemDelegate
::updateEditorGeometry(QWidget *editor,
editor->setGeometry(option.rect);
}
void CBItemDelegate
::paint(QPainter *painter,
bool data = index.model()->data(index, Qt::DisplayRole).toBool();
checkboxstyle.rect = option.rect;
checkboxstyle.rect.setLeft(option.rect.x() + option.rect.width()/2 - checkbox_rect.width()/2);
if(data)
checkboxstyle.
state = QStyle::State_On|QStyle
::State_Enabled;
else
checkboxstyle.
state = QStyle::State_Off|QStyle
::State_Enabled;
}
#include "cbitemdelegate.h"
#include <QApplication>
#include <QtGui>
CBItemDelegate::CBItemDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
QWidget *CBItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
QCheckBox *editor = new QCheckBox(parent);
editor->installEventFilter(const_cast<CBItemDelegate*>(this));
return editor;
}
void CBItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const {
int value = index.model()->data(index, Qt::DisplayRole).toInt();
QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
if(value == 1)
checkBox->setCheckState(Qt::Checked);
else
checkBox->setCheckState(Qt::Unchecked);
}
void CBItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const {
QCheckBox *checkBox = static_cast<QCheckBox*>(editor);
int value;
if(checkBox->checkState() == Qt::Checked)
value = 1;
else
value = 0;
model->setData(index, value);
}
void CBItemDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
editor->setGeometry(option.rect);
}
void CBItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const {
bool data = index.model()->data(index, Qt::DisplayRole).toBool();
QStyleOptionButton checkboxstyle;
QRect checkbox_rect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkboxstyle);
checkboxstyle.rect = option.rect;
checkboxstyle.rect.setLeft(option.rect.x() + option.rect.width()/2 - checkbox_rect.width()/2);
if(data)
checkboxstyle.state = QStyle::State_On|QStyle::State_Enabled;
else
checkboxstyle.state = QStyle::State_Off|QStyle::State_Enabled;
QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkboxstyle, painter);
}
To copy to clipboard, switch view to plain text mode
I then create an instance to a CBItemDelegate, and use setItemDelegateForColumn to install it to the view.
When I first bring the table up, it looks wonderful, all of the checkboxes are checked/unchecked appropriately, and they are all centered horizontally and vertically in their cells, thanks to the paint procedure.
Then when I click to edit the cells things start to go wrong. The checkbox jumps to the side of the cell, it responds, it is just on the side. I presume it is because in the createEditor function I am creating an actual QCheckBox with its attached (blank) QLabel, and that throws things off. Could somebody please help me past this point?
Bookmarks