PDA

View Full Version : Set an editable column for QTableView



SIFE
12th March 2012, 18:35
I wont to set an editable column in QTableView, so far I tried to subclass QTableView and reimplementing Qt::ItemFlags flags(const QModelIndex & index) const, subclassing QSqlQueryModel and reimplementing Qt::ItemFlags flags(const QModelIndex & index) const, finally, subclassing QAbstractItemView, but this a compiler error showed up.
Subclassing QTableView

#include "exqtableview.h"

ExQTableView::ExQTableView(QWidget *parent) :
QTableView(parent)
{
}

Qt::ItemFlags ExQTableView::flags(const QModelIndex & index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
if (index.column() == 2)
return index.parent().flags() & ~Qt::ItemIsEditable;
}
Subclassing QSqlQueryModel

#include "exsqlquerymodel.h"

ExSqlQueryModel::ExSqlQueryModel(QObject *parent) :
QSqlQueryModel(parent)
{
}

Qt::ItemFlags ExSqlQueryModel::flags( const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 2 )
flags &= ~Qt::ItemIsEditable;
return flags;
}
Subclassing QAbstractItemView

#include "exitemdelegate.h"
#include <QTableWidgetItem>

ExItemDelegate::ExItemDelegate(QObject *parent) :
QItemDelegate(parent)
{
}

QWidget *ExItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & ,
const QModelIndex & index ) const
{
QTableWidgetItem *item = new QTableWidgetItem;
return item;
}

void ExItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
float value = index.model()->data(index, Qt::EditRole).toFloat();

QTableWidgetItem *cell = static_cast<QTableWidgetItem*>(editor);
cell->setData(0, value);
}

void ExItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QTableWidgetItem *cell = static_cast<QTableWidgetItem*>(editor);
float value = cell->data(Qt::DisplayRole);
model->setData(index, value, Qt::EditRole);
}

void ExItemDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &) const
{
editor->setGeometry(option.rect);
}
So, what wrong I am doing here?

ChrisW67
13th March 2012, 01:10
Neither QAbstractItemView nor the derived QTableView has as flags() function to override. This leaves your other option.


I wont to set an editable column in QTableView

Then you should add the Qt::ItemIsEditable flag. Your code currently removes the flag by using a bitwise AND with the negation of the editable flag value. You want to use a bitwise OR to add the flag.

SIFE
14th March 2012, 02:03
I subclassed from QSqlQueryModel and reimplmented flags(), now my QTableView is editable.

Qt::ItemFlags EditableSqlModel::flags(
const QModelIndex &index) const
{
Qt::ItemFlags flags = QSqlQueryModel::flags(index);
if (index.column() == 1 || index.column() == 2)
flags |= Qt::ItemIsEditable;
return flags;
}
However, when I changed some data in cell, and after hint enter, the value back to the first one before I edit, is there some way to keep changed data in view, and how to reimplemnt cellChanged(int, int) in QTableView?

ChrisW67
14th March 2012, 02:19
QSqlQueryModel is read-only by design. Its inherited setData() does nothing and returns false. You could implement setData() to put the data into the database, but it won't show in the view until you rerun the query. setData() could also emit a cellChanged() signal if you so desired.

SIFE
14th March 2012, 23:47
I am trying to avoid setData() because I have many things depend on widget. QTableView has no cellChanged() signal, how suppose I catch user modification in view?

ChrisW67
15th March 2012, 00:09
You want to modify the data in the model, but you want to avoid setData()? Sorry, you've lost me. Using the model mechanisms is precisely the way you ensure that all views on the model stay in sync.

By placing a delegate on the view you can intercept the attempt to write data back into the model, see QItemDelegate::setModelData().