PDA

View Full Version : QTableView and QSqlTableModel problem



Misenko
19th August 2008, 01:24
Hi.

I want to know how to make sure that I wont can let some cell of my view empty.
For example I doubleclicked cell and started write. I rite something and than I press enter or tab or arrow. But when I write nothing, when I let the cell empty and press enter or tab or narrow or click somewhere I want to application set the empty cell as current and call edit().
It sounds pretty easy but I dont know which signal may i use. I tried to use dataChanged with top and bottom modelindexes but it doesnt work and I dont know why. Thisi im the code:

void DB::dataChanged(const QModelIndex &top, const QModelIndex &bottom)
{
if(!top.isValid())
return;
QString data;
data = top.data().toString();
if (data.isEmpty())
{
view->setCurrentIndex(top);
view->edit(top);
}

I tried some other signals from QTableView and QSqlTableModel but nothing works perfectly for me.

Can anyone help me?

spirit
19th August 2008, 08:49
you can use your own delegate and then reimplement QItemDelegate::eventFilter.
or more complex method, you can inherit from QTableView and reimplement QAbstractItemView::edit.

Misenko
19th August 2008, 17:40
But why this dont work? Or is there other way to do that with signals-slots system?

Can you tell me how to reimplement these functions? Please show me some example how to do that if you can.

Thanks.

spirit
19th August 2008, 18:36
But why this dont work? Or is there other way to do that with signals-slots system?


when you call setCurrentIndex then editor will be closed after that QItemDelegate::setModelData is called and empty value set in model.



...
void LineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
QString value = lineEdit->text();

if (value.isEmpty()) {
QMetaObject::invokeMethod(const_cast<LineEditDelegate *>(this), "keepEditorOpened", Qt::QueuedConnection, Q_ARG(QModelIndex, index));
return;
}

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


signal


signals:
void keepEditorOpened(const QModelIndex &index);

must be deslarated in lineeditdelegate.h

then in widget do next


MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
QStandardItemModel *model = new QStandardItemModel(4, 2);
tableView = new QTableView();
tableView->setModel(model);

LineEditDelegate *delegate = new LineEditDelegate();
tableView->setItemDelegate(delegate);
connect(delegate, SIGNAL(keepEditorOpened(const QModelIndex &)), SLOT(openEditor(const QModelIndex &)));

for (int row = 0; row < 4; ++row) {
for (int column = 0; column < 2; ++column) {
QModelIndex index = model->index(row, column, QModelIndex());
model->setData(index, QVariant((row+1) * (column+1)));
}
}
...
void MainWindow::openEditor(const QModelIndex &index)
{
tableView->edit(index);
}


I hope this is not complicated example. :)

Misenko
19th August 2008, 22:47
Thank you man it works perfectly with data which are already in database. But when I add new row it doesnt check it before I submit the model.
Let me explain. I have model edit strategy set to QSqlTableModel::OnManualSubmit.
So I have QPushButton apply on which I click this slot is activated:

void DB::applyF()
{
if (!check())
return;
model->database().transaction();
if (model->submitAll())
{
model->database().commit();
}
else
{
model->database().rollback();
QMessageBox::warning(this, tr("Cached Table"),
tr("The database reported an error: %1")
.arg(model->lastError().text()));
}
}

and storno button whit this slot:

void DB::stornoF()
{
model->revertAll();
}

and add and remove buttons with thier slots:


void DB::addF()
{
model->insertRow(model->rowCount());
view->setCurrentIndex(model->index(model->rowCount()-1,0));
view->edit(model->index(model->rowCount()-1,0));
}

void DB::removeF()
{
model->removeRow(view->currentIndex().row());
}

So when I press add row is added to the view only with asterisk and with remove row has exclamation mark until I press apply button.

And with this added row before I press apply it doesnt work at all.

How can I make it to check this cells too?

PS: Sorry about my english :o

Misenko
19th August 2008, 22:58
Sorry I was mistaken. It doesnt wark at all. When I let the cell empty end pres enter or tab or something it give back the text which was there but dont get it into edit mode. It explains the added rows it do the same with them but they were empty so given text is nothing. I think that the slot is not activated or signal is not send. How Can I fix it?