Solved best practices: I'm doing it wrong
-
I've created an edit dialog, but I'm not able to map the individual elements to the model as I did in the main widget. I create the edit dialog like this:
DeviceModel *m_d; ... void Widget::on_pushButtonEdit_clicked() { EditDialog editDialog(m_d); QObject::connect(&editDialog, &EditDialog::editCommitPressed, this, &Widget::sendCommit); editDialog.exec(); }
And I try to map to the model like this (seemingly identical to how I do it in the main widget):
EditDialog::EditDialog(DeviceModel *d, QWidget *parent) : QDialog(parent), ui(new Ui::EditDialog) { ui->setupUi(this); m_mapper = new QDataWidgetMapper(this); m_mapper->setModel(d->getModel()); m_mapper->addMapping(ui->deviceName, TAG_DEVICENAME);
The mapping works in the main widget, but not for my edit dialog. Any ideas what I'm doing wrong? Thanks.
-
Did you forget to connect to setCurrentModelIndex?
-
Well...maybe.
In my main widget, I have this line:
QObject::connect(ui->tableView->selectionModel(), &QItemSelectionModel::currentRowChanged, m_mapper, &QDataWidgetMapper::setCurrentModelIndex);
Wouldn't that be sufficient for anything using the same model?
-
@mzimmers said in best practices: I'm doing it wrong:
for anything using the same model
The connect uses the selection of the view and the mapper so has nothing to do with the model.
If either the view or them_mapper
are different objects from those in the main window then you have to redo the connection -
Oh, OK, I think I see the problem: since my edit dialog doesn't have a QTableView, there's no way to select a row (no table --> no rows). I guess I can't just have the details mapped without some table to give it context, right?
So, do I need an invisible table in my edit dialog, or is there some more clever way around this?
-
No, you can also just straight call
m_mapper->setCurrentModelIndex(index);
whereindex
is the index of the model you want to load without doing any connection -
I'm getting a bad index back. Here's my c'tor:
EditDialog::EditDialog(DeviceModel *d, QWidget *parent) : QDialog(parent), ui(new Ui::EditDialog) { ui->setupUi(this); m_mapper = new QDataWidgetMapper(this); m_mapper->setModel(d->getModel()); int i = m_mapper->currentIndex(); QModelIndex qmi = d->getModel()->index(i, 0); m_mapper->setCurrentModelIndex(qmi);
The variable i is set to (-1). What might I be doing wrong?
-
create a public method in the dialog:
void EditDialog::loadIndex(const QModelIndex& idx){m_mapper->setCurrentModelIndex(idx);}
After
EditDialog editDialog(m_d);
, add
editDialog.loadIndex(ui->tableView->selectionModel()->currentIndex());
-
@VRonin a couple questions, please:
- EditDialog doesn't have a method setCurrentModelIndex(). Perhaps you meant:
QDataWidgetMapper *m_mapper; ... m_mapper.setCurrentModelIndex(ui->tableView->selectionModel()->currentIndex());
- How does loadIndex() get invoked?
Thanks...
-
Edited the answer above.
editDialog.setCurrentModelIndex
should have beeneditDialog.loadIndex
sorry -
Clever...very clever. So, to summarize:
- it's generally a good idea to perform editing in a separate window/dialog.
- create this window with new->Qt Designer Form Class; this create everything at once.
- use the QDataWidgetMapper in the edit dialog to display the details from the model.
- use VRonin's technique of setting the model index for the edit dialog by using the index from the parent window.
I'll edit the summary if anyone informs me of errata. Thanks for all the assistance.