QSqlRelationalTableModel with multiple Joins?
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
You are using aQTableView
, right? You can use that against aQSqlQueryModel
, which is a model based against a query rather than an actual table.No, I'm using a QSqlQueryModel
_queryModel = new QSqlQueryModel(ui->tableView); _queryModel->setQuery("SELECT Employee.id, Employee.Name, Employee.Surname, Birthplace.Name as 'Birthplace', Employee.Birthdate, Residence.Name as 'Residence', Employee.Qualification, Position.Name as 'Position', EmployeePosition.EngagementDate, Resource.Name as 'Resource', EmployeeResource.AcquisitionDate" "FROM Employee" "LEFT JOIN EmployeePosition ON Employee.id = EmployeePosition.idEmployee" "LEFT JOIN Position ON EmployeePosition.idPosition = Position.id" "LEFT JOIN EmployeeResource ON Employee.id = EmployeeResource.idEmployee" "LEFT JOIN Resource ON Resource.id = EmployeeResource.idResource" "LEFT JOIN Country AS Birthplace ON Employee.BirthplaceID = Birthplace.id" "LEFT JOIN Country AS Residence ON Employee.ResidenceID = Residence.id", *_db); ui->tableView->setModel(_queryModel); ui->tableView->show();
And the Table View is blank
I also tried with QSqlTableModel
_tableModel = new QSqlTableModel(ui->tableView, *_db); QString myQuery = "SELECT Employee.id, Employee.Name, Employee.Surname, Birthplace.Name as 'Birthplace', Employee.Birthdate, Residence.Name as 'Residence', Employee.Qualification, Position.Name as 'Position', EmployeePosition.EngagementDate, Resource.Name as 'Resource', EmployeeResource.AcquisitionDate" "FROM Employee" "LEFT JOIN EmployeePosition ON Employee.id = EmployeePosition.idEmployee" "LEFT JOIN Position ON EmployeePosition.idPosition = Position.id" "LEFT JOIN EmployeeResource ON Employee.id = EmployeeResource.idEmployee" "LEFT JOIN Resource ON Resource.id = EmployeeResource.idResource" "LEFT JOIN Country AS Birthplace ON Employee.BirthplaceID = Birthplace.id" "LEFT JOIN Country AS Residence ON Employee.ResidenceID = Residence.id"; _tableModel->setTable(myQuery ); _tableModel->setEditStrategy(QSqlTableModel::OnManualSubmit); _tableModel->select(); ui->tableView->setModel(_tableModel); ui->tableView->show();
Same issue: Table View is blank.
@devhobby
I was asking you to confirm that inui->tableView->setModel(_queryModel);
the type of yourui->tableView
is aQTableView
?Anyway, assuming it is, what's this:
_queryModel = new QSqlQueryModel(ui->tableView);
What's that parent doing there? (Haven't seen this before, just checking.)
Does
QSqlQueryModel::lastError()
tell you anything aftersetQuery()
or later?Hang on! I don't do C++, but the way you've written your query, does C++ join the strings with a space between? Because if not (and I don't think it does) your words are all touching each other, and you have a SQL error!! Make sure your query is right, and check that
lastError()
thing, e.g.QSqlQueryModel model; model.setQuery("select *" "from MyTable"); if (model.lastError().isValid()) qDebug() << model.lastError();
Because I think the principle should be working fine otherwise.
-
@devhobby
I was asking you to confirm that inui->tableView->setModel(_queryModel);
the type of yourui->tableView
is aQTableView
?Anyway, assuming it is, what's this:
_queryModel = new QSqlQueryModel(ui->tableView);
What's that parent doing there? (Haven't seen this before, just checking.)
Does
QSqlQueryModel::lastError()
tell you anything aftersetQuery()
or later?Hang on! I don't do C++, but the way you've written your query, does C++ join the strings with a space between? Because if not (and I don't think it does) your words are all touching each other, and you have a SQL error!! Make sure your query is right, and check that
lastError()
thing, e.g.QSqlQueryModel model; model.setQuery("select *" "from MyTable"); if (model.lastError().isValid()) qDebug() << model.lastError();
Because I think the principle should be working fine otherwise.
@JonB said in QSqlRelationalTableModel with multiple Joins?:
does C++ join the strings with a space between? Because if not (and I don't think it does) your words are all touching each other, >and you have a SQL error!! Make sure your query is right, and check thatlastError()
thing, e.g.
Because I think the principle should be working fine otherwise.Oh gosh! I completely forgot to put the spaces before each line! Thanks
By the way, once that I get all of this setup... now I need to find a way to customize a cell (item).
I successfully retrieve its index... but I'd like to change its background color, for instanceAnd since I'm using a Table View and not a Table Widget, I only see item delegates.
How can I achieve what I want?
-
@VRonin said in QSqlRelationalTableModel with multiple Joins?:
Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I just want to change the data of the cell and, once changed, color that cell in a different color to alert the user of the change of that particular item/cell.
Seems a lot of hard-coding work... maybe I should find another convenient way... but for now let's see what comes out
-
@VRonin said in QSqlRelationalTableModel with multiple Joins?:
Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I just want to change the data of the cell and, once changed, color that cell in a different color to alert the user of the change of that particular item/cell.
Seems a lot of hard-coding work... maybe I should find another convenient way... but for now let's see what comes out
-
@devhobby
If you want to edit in aQTableView
(right?), what have you set your http://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop to?@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
If you want to edit in aQTableView
(right?), what have you set your http://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop to?QAbstractItemView::DoubleClicked
ui->tableView->setModel(_queryModel); ui->tableView->verticalHeader()->hide(); ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked); ui->tableView->show();
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
If you want to edit in aQTableView
(right?), what have you set your http://doc.qt.io/qt-5/qabstractitemview.html#editTriggers-prop to?QAbstractItemView::DoubleClicked
ui->tableView->setModel(_queryModel); ui->tableView->verticalHeader()->hide(); ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked); ui->tableView->show();
@devhobby
And you are saying that when you double-click...? Nothing at all happens?If that is the case, I can only imagine your model is read-only, to do with it being a
SELECT
and not a table? To be clear, you won't be "changing the data of the cell" per se, you'll be changing the data in the model that cell is displaying. -
@devhobby
And you are saying that when you double-click...? Nothing at all happens?If that is the case, I can only imagine your model is read-only, to do with it being a
SELECT
and not a table? To be clear, you won't be "changing the data of the cell" per se, you'll be changing the data in the model that cell is displaying.@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
And you are saying that when you double-click...? Nothing at all happens?If that is the case, I can only imagine your model is read-only, to do with it being a
SELECT
and not a table?Yes, as stated above I used my custom query to do all the joins.
By the way, I don't expect to change the database directly.
I just want to visually edit the cell without applying any changes to the database.
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
When the user presses the button "Commit changes" I will have a series of changes that the user wants to apply to the database -> I now need to make them real sending a custom query to the database.
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
And you are saying that when you double-click...? Nothing at all happens?If that is the case, I can only imagine your model is read-only, to do with it being a
SELECT
and not a table?Yes, as stated above I used my custom query to do all the joins.
By the way, I don't expect to change the database directly.
I just want to visually edit the cell without applying any changes to the database.
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
When the user presses the button "Commit changes" I will have a series of changes that the user wants to apply to the database -> I now need to make them real sending a custom query to the database.
@devhobby
I'm a little lost. You wrote:Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I thought you were saying when double-click it does not let you edit, nothing happens, or whatever. Now I think you're saying it does let you edit? I don't know if you have a question here?
-
@devhobby
I'm a little lost. You wrote:Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I thought you were saying when double-click it does not let you edit, nothing happens, or whatever. Now I think you're saying it does let you edit? I don't know if you have a question here?
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
I'm a little lost. You wrote:Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I thought you were saying when double-click it does not let you edit, nothing happens, or whatever. Now I think you're saying it does let you edit? I don't know if you have a question here?
Yes I asked if there's a way to change the content of the cell by directly typing into it
Because now, when I double click, nothing happens.
Once the cell is edited, I'd also like to change its background color... but that's another story
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
I'm a little lost. You wrote:Thanks but before doing that, I was wondering if there's a way to change the content of the cell by directly typing into it.
I thought you were saying when double-click it does not let you edit, nothing happens, or whatever. Now I think you're saying it does let you edit? I don't know if you have a question here?
Yes I asked if there's a way to change the content of the cell by directly typing into it
Because now, when I double click, nothing happens.
Once the cell is edited, I'd also like to change its background color... but that's another story
@devhobby said in QSqlRelationalTableModel with multiple Joins?:
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
Because now, when I double click, nothing happens.
Sorry, but if "nothing happens" when you double-click cell to edit, how come you talk about "Once the user changes the text of the cell"? Maybe I'm being dumb, but I just don't get it!
-
@devhobby said in QSqlRelationalTableModel with multiple Joins?:
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
Because now, when I double click, nothing happens.
Sorry, but if "nothing happens" when you double-click cell to edit, how come you talk about "Once the user changes the text of the cell"? Maybe I'm being dumb, but I just don't get it!
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby said in QSqlRelationalTableModel with multiple Joins?:
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
Because now, when I double click, nothing happens.
Sorry, but if "nothing happens" when you double-click cell to edit, how come you talk about "Once the user changes the text of the cell"? Maybe I'm being dumb, but I just don't get it!
Don't worry! I'm sorry, I'm probably using the wrong tenses to express myself.
"Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString"
Is the prediction of what I want to happen... and can't manage to make it happen actually
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby said in QSqlRelationalTableModel with multiple Joins?:
Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString
Because now, when I double click, nothing happens.
Sorry, but if "nothing happens" when you double-click cell to edit, how come you talk about "Once the user changes the text of the cell"? Maybe I'm being dumb, but I just don't get it!
Don't worry! I'm sorry, I'm probably using the wrong tenses to express myself.
"Once the user changes the text of the cell, the new text is immediately visible and I store it in a QString"
Is the prediction of what I want to happen... and can't manage to make it happen actually
Is the prediction of what I want to happen... and can't manage to make it happen actually
Ohhhh...! :)
OK, I would expect you've done the right stuff. I believe that's what our code does. I can only think of what I suggested: that the
SELECT
makes the model read-only, and editing is not allowed.I shall step aside and you need an expert here to guide you further....
-
Is the prediction of what I want to happen... and can't manage to make it happen actually
Ohhhh...! :)
OK, I would expect you've done the right stuff. I believe that's what our code does. I can only think of what I suggested: that the
SELECT
makes the model read-only, and editing is not allowed.I shall step aside and you need an expert here to guide you further....
@JonB said in QSqlRelationalTableModel with multiple Joins?:
Is the prediction of what I want to happen... and can't manage to make it happen actually
Ohhhh...! :)
OK, I would expect you've done the right stuff. I believe that's what our code does. I can only think of what I suggested: that the
SELECT
makes the model read-only, and editing is not allowed.I shall step aside and you need an expert here to guide you further....
Yes, the custom query is most likely keeping my Table View read-only.
I just want to visually edit the cells...
This is far more complicated than I thought...
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
Is the prediction of what I want to happen... and can't manage to make it happen actually
Ohhhh...! :)
OK, I would expect you've done the right stuff. I believe that's what our code does. I can only think of what I suggested: that the
SELECT
makes the model read-only, and editing is not allowed.I shall step aside and you need an expert here to guide you further....
Yes, the custom query is most likely keeping my Table View read-only.
I just want to visually edit the cells...
This is far more complicated than I thought...
@devhobby
http://doc.qt.io/qt-5/qitemdelegate.html#details must be to do with it.I could easily be wrong(!), but I thought the idea of the model/view would be that if you edit it would save the value back to the model, not "just give you some string". You can doubtless play with the delegate to do something else...
P.S.
Look at http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells:Check if the item is actually editable: (
MyTable->model()->flags(idx) & Qt::ItemIsEditable
). If not, make it so.Setting a Qt.ItemIsEnabled flag makes the QTableView items editable. To enter the item's editing mode the user can simply double-click it.
EDIT: You have to loop over every item in your table view to make it individually editable....
-
@devhobby
http://doc.qt.io/qt-5/qitemdelegate.html#details must be to do with it.I could easily be wrong(!), but I thought the idea of the model/view would be that if you edit it would save the value back to the model, not "just give you some string". You can doubtless play with the delegate to do something else...
P.S.
Look at http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells:Check if the item is actually editable: (
MyTable->model()->flags(idx) & Qt::ItemIsEditable
). If not, make it so.Setting a Qt.ItemIsEnabled flag makes the QTableView items editable. To enter the item's editing mode the user can simply double-click it.
EDIT: You have to loop over every item in your table view to make it individually editable....
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
http://doc.qt.io/qt-5/qitemdelegate.html#details must be to do with it.I could easily be wrong(!), but I thought the idea of the model/view would be that if you edit it would save the value back to the model, not "just give you some string". You can doubtless play with the delegate to do something else...
P.S.
Look at http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells:Check if the item is actually editable: (
MyTable->model()->flags(idx) & Qt::ItemIsEditable
). If not, make it so.Setting a Qt.ItemIsEnabled flag makes the QTableView items editable. To enter the item's editing mode the user can simply double-click it.
I'd like to change Table View's flag to Qt::ItemIsEditable... but can't find a way to do it
There's no setFlags() method here...
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
http://doc.qt.io/qt-5/qitemdelegate.html#details must be to do with it.I could easily be wrong(!), but I thought the idea of the model/view would be that if you edit it would save the value back to the model, not "just give you some string". You can doubtless play with the delegate to do something else...
P.S.
Look at http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells:Check if the item is actually editable: (
MyTable->model()->flags(idx) & Qt::ItemIsEditable
). If not, make it so.Setting a Qt.ItemIsEnabled flag makes the QTableView items editable. To enter the item's editing mode the user can simply double-click it.
I'd like to change Table View's flag to Qt::ItemIsEditable... but can't find a way to do it
There's no setFlags() method here...
@devhobby
You have to loop over every item in your table view to make it individually editable (if you're not creating the items yourself, or unless someone suggests a way to cause that to happen as it binds to your model, e.g. https://stackoverflow.com/a/28226056/489865).... -
@devhobby
You have to loop over every item in your table view to make it individually editable (if you're not creating the items yourself, or unless someone suggests a way to cause that to happen as it binds to your model, e.g. https://stackoverflow.com/a/28226056/489865)....@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
You have to loop over every item in your table view to make it individually editable (if you're not creating the items yourself, or unless someone suggests a way to cause that to happen as it binds to your model)....Suppose I'm inside a for loop where index is a QModelIndex
ui->tableView->model()->data(index). ???
There's no setFlags here still
-
@JonB said in QSqlRelationalTableModel with multiple Joins?:
@devhobby
You have to loop over every item in your table view to make it individually editable (if you're not creating the items yourself, or unless someone suggests a way to cause that to happen as it binds to your model)....Suppose I'm inside a for loop where index is a QModelIndex
ui->tableView->model()->data(index). ???
There's no setFlags here still
I think we use
QTableWidget
, not justQTableView
.http://www.qtcentre.org/threads/46245-QTableWidgetItem-setflags-strange-behavior?p=209282#post209282 shows you accessing
QTableWidgetItem
. http://doc.qt.io/qt-5/qtablewidget.html#itemhttp://doc.qt.io/qt-5/qtablewidget.html#details:
The QTableWidget class provides an item-based table view with a default model.
Table widgets provide standard table display facilities for applications. The items in a QTableWidget are provided by QTableWidgetItem.
If you want a table that uses your own data model you should use QTableView rather than this class.But for
QTableView
I previously gave you http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells?p=176235#post176235:Qt::ItemFlags MyTableModel::flags (const QModelIndex &index) const { return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; }
http://doc.qt.io/qt-5/qabstractitemmodel.html#flags, http://doc.qt.io/qt-5/qabstracttablemodel.html#flags works off the model, so presumably your
ui->tableView->model()->flags(index)
.Ah ha!! Here's what we wanted to know:
http://doc.qt.io/qt-5/qsqlquerymodel.html#detailsThe model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags(). Another option is to use QSqlTableModel, which provides a read-write model based on a single database table.
-
I think we use
QTableWidget
, not justQTableView
.http://www.qtcentre.org/threads/46245-QTableWidgetItem-setflags-strange-behavior?p=209282#post209282 shows you accessing
QTableWidgetItem
. http://doc.qt.io/qt-5/qtablewidget.html#itemhttp://doc.qt.io/qt-5/qtablewidget.html#details:
The QTableWidget class provides an item-based table view with a default model.
Table widgets provide standard table display facilities for applications. The items in a QTableWidget are provided by QTableWidgetItem.
If you want a table that uses your own data model you should use QTableView rather than this class.But for
QTableView
I previously gave you http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells?p=176235#post176235:Qt::ItemFlags MyTableModel::flags (const QModelIndex &index) const { return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; }
http://doc.qt.io/qt-5/qabstractitemmodel.html#flags, http://doc.qt.io/qt-5/qabstracttablemodel.html#flags works off the model, so presumably your
ui->tableView->model()->flags(index)
.Ah ha!! Here's what we wanted to know:
http://doc.qt.io/qt-5/qsqlquerymodel.html#detailsThe model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags(). Another option is to use QSqlTableModel, which provides a read-write model based on a single database table.
@JonB said in QSqlRelationalTableModel with multiple Joins?:
I think we use
QTableWidget
, not justQTableView
.http://www.qtcentre.org/threads/46245-QTableWidgetItem-setflags-strange-behavior?p=209282#post209282 shows you accessing
QTableWidgetItem
. http://doc.qt.io/qt-5/qtablewidget.html#itemhttp://doc.qt.io/qt-5/qtablewidget.html#details:
The QTableWidget class provides an item-based table view with a default model.
Table widgets provide standard table display facilities for applications. The items in a QTableWidget are provided by QTableWidgetItem.
If you want a table that uses your own data model you should use QTableView rather than this class.But for
QTableView
I previously gave you http://www.qtcentre.org/threads/38338-Can-t-edit-my-QTableView-cells?p=176235#post176235:Qt::ItemFlags MyTableModel::flags (const QModelIndex &index) const { return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; }
At this point I don't even know which of the 2 (table view/table widget) is the most appropriate for my situation.
The last post you linked says to reimplement the method flags() but I don't understand: after inheriting from AbstractItemModel (and reimplementing the method), what am I supposed to do?