QSqlRelationalDelegate in QSqlRelationalTableModel shows foreign key instead of its value - c++

Here is my code:
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this, db1);
model->setTable("syllabi");
model->setRelation(3, QSqlRelation("activity_types", "activity_type_id", "activity_type_name"));
model->select();
ui->tableView->setModel(model);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
Values in combo boxes show correctly, but when I change the value and select another cell of the table, the cell shows the ID (foreign key) instead of its value.
Also, when I insert another value with this code
model->insertRow(model->rowCount());
model->setData(model->index(model->rowCount()-1, 0), teacherName);
there is a error:
QODBCResult::exec: Unable to execute statement: "[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value 'default' to data type int."
The tables did't join correctly?
EDIT:
Okay, now when I change value in combo box it deletes the whole row. What might be the reason?
The tables: https://yadi.sk/i/ujL15zD_hupvz

I know it's pretty late, but anyway, here is the answer.
I have encountered the same problem but in pyqt. The problem was with EditStrategy.OnFieldChange That should behave like OnRowChange when inserting a new row but somehow keeps skipping lookups for relations during the edit of the new row. Changing the EditStrategy to OnRowChange solves the problem.
Here is the original answer I got for my problem.

Related

How to create a field with a list of choices but store the index?

I'm making a Microsoft Access table where one of the fields is a list of pre-made options. When I make a SQL query on that table it returns the values of the list as strings containing the spelled out choice. I would like to assign numerical values to each element of the list so a SQL query returns a number instead. How do I do this? I know it's possible because I have an access file with such a list but I'm unable to recreate it.
An easy way to do this is to have your combo box use a query of the table as a Rowsource. This query would have the table unique ID in the first field and the field you wish to return as the second field. Then change the setting on the combo box for "Column Count" to 2. If you want to show both fields change the "Column Widths" value to 1"; 1". If you want to show only one field, change the value of one you do not want to see to 0. Now we you refer to this list in an SQL queries, it will use the ID field but show the user the string field.

How to insert programmatically a value in a new row of a QtableView

I'm using a QtableView to display and edit data from a QsqlTableModel.
Everything's fine : data from a postgreSQL table is displayed, and user can edit it and save modifications.
I want to add a row when uses click on a button. I use the insertRecord method from my QslTableModel.
The row is correctly added in the QTableView.
My problem is :
I want to insert a value from a query in the first cell of this new row. (to automatically populate an unique identifier).
This is my code :
def ajoutlgn(self):
query_idNewLine = QtSql.QSqlQuery(self.db)
if query_idNewLine.exec_('SELECT sp_idsuivi+1 FROM bdsuivis.t_suivprev_tablo ORDER BY sp_idsuivi DESC LIMIT 1'):
while query_idNewLine.next():
identifiant = query_idNewLine.value(0)
#print identifiant
record = QtSql.QSqlRecord()
record.setValue(1,identifiant)
self.model.insertRecord(self.model.rowCount(), record)
The value is not inserted in the new row (but if I enter a value by hand, it works perfectly).
Nevertheless, the query is OK (as I can see with the « print identifiant » line, which returns the expected integer).
Do you see what I'm doing wrong ?
Are there other methods to insert programmatically a value in a QTableView cell?
Or do I have to use a QitemDelegate ?
Thanks for advance.
Finally I found the solution :
This line creates a record, but not a record for my QsqlTableModel
record = QtSql.QSqlRecord()
I replaced it with this one, and it works perfectly :
record = self.model.record()

list of SelectedRows in QTableWidget

I have problem getting selected rows from QTableWidget. I have table like this:
[id] [ key ]
0 test
1 pass
I want to get every row's key values. I tried QTableWidget->selectedIndexes(); but it says it's protected and I can't access that. When I tried QTableWidget->SelectionModel->selectedIndexes, I don't know how to loop through list and get the key values. Do anyone know better way how can I do it?
Regards.
I'm assuming that you set the selection behavior of your table widget to select rows.
You can always access the so-called "selection model" of any item view/widget. QTableWidget inherits from QAbstractItemView, which gives you access to this special model. This model can tell you the selected rows as a list of QModelIndex, which can then tell you the row. Once you've got them, you can access the table content, in your case the text in the column with index 1 (key column).
static const KEY_COLUMN = 1;
QList<QString> selectedKeys;
QItemSelectionModel *selectionModel = ui->tableWidget->selectionModel();
foreach(QModelIndex index, selectionModel->selectedRows())
selectedIDs << ui->tableWidget->item(index->row(), KEY_COLUMN)->text();
Because you are using QTableWidget, you probably want to be calling selectedItems(). Your results will be based on what you have set the selection behavior to, via setSelectionBehavior()
When you have a list of items, you can specifically get the second column item (if it wasn't selected already):
QTableWigetItem *keyItem = table->item(anItem->row(), 1);
QString val = keyItem->text();

connect QTreeWidgetItem to database

Im working on a project where im trying to build a QTreeWidget that has multiple QTreeWidgetItems
and once i click on a particular item it connects to a database and shows a query result in a tableview model, until now every thing works fine.
the problem is that i want each item to output different resut depending on some criteria on the same table where this criteria is only changing the value of an attribute, and this value is the same of the item name. for example item named 122 and the table has atribute called no. when we click on item 122 the result of this query must be shown (select * from table where no=122)
any help :)
I am assuming you have a QTableView backed by a QSqlQueryModel or QSqlTableModel.
You can connect to the signal QTreeWidget::itemSelectionChanged() and then in the slot you get the current item with selectedItems()[0]. Then you create your query:
QSqlQuery query;
query.prepare("select * from table where no=:no");
query.bindValue(":no", number);
query.exec();
Finally you can use setQuery (const QSqlQuery & query) on the model. This should update your view.
I hope I understood correctly what you want to achieve.

Trying to modify read-only DataSet field

I use C++ Builder 6.0
I use TADODataSet execute following SQL statement:
SELECT Id, SUM(Saldo) AS Saldo
FROM Table
GROUP BY Id
I use this DataSet only for reporting. No need update date back to database.
When I try to modify field "Saldo"
adospCard->Edit();
adospCard->FieldByName("Saldo")->AsFloat=0.0;
adospCard->Post();
I get error:
Field 'Saldo' cannot be modified.
I add this line
adospCard->FieldByName("Saldo")->ReadOnly=false;
and error no more occurred, but field 'Saldo' has not changed.
adospCard->Edit();
//adospCard->FieldByName("Saldo")->AsFloat=1536.5
adospCard->FieldByName("Saldo")->AsFloat=0.0;
//adospCard->FieldByName("Saldo")->AsFloat=0
adospCard->Post();
//adospCard->FieldByName("Saldo")->AsFloat=1536.5
Howe to change ‘Saldo’ field value?
Add a calculated field to your dataset.
Calculate the right value for Saldo
in this calculated field (you can
use Saldo as source for it if you
want to)
display this calculated field in your report in
stead of the Saldo field.
Edit:
For examples of how to add calculated fields, see for instance here, here and here.
--jeroen
As ldsandon said, you cannot modify the "Saldo" field as it is computed.
If you need to set the value to zero when Id is "something" you are better off doing it in your query. The best approach depends on the criteria for setting the value to zero.
Or, save the results of the original query in a temp table then modify that before returning the results to the report.
Finally, what reporting tool are you using? Can that do the "Saldo = 0" change when rendering the report?
Consider storing your result in a ClientDataset - if you can be assured the result isn't too large.
I don't use "TADODataSet" so the following may not apply :)...
When I do the same (or similar) using my DB of choice (i.e. Advantage Database Server) I would use the INTO clause, albeit, with a TSQLQuery component (with the RequestLive property enabled). For example:
SELECT Id, SUM(Saldo) AS Saldo INTO #TempTable FROM Table GROUP BY Id