Qt - Mapping two tables on the widgets using QDataWidgetMapper - qt

There are two tables in SQLite. For a simple example, person and address.
How to map data of the current man from both tables to form widgets? How should we synchronize the current index of the two tables, if we use two QDataWidgetMapper's?
Is there another approach to display related data on the form, including insertion?
I would be very grateful for your help and examples.

If I got you right, you want to join two SQL tables (say person and address). If this is the case, you would need a QSqlQueryModel.
Note that QDataWidgetMapper is used for sharing a single model among multiple widgets. However in this case, it seems you want to show data from two tables in one widget.
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT name, city FROM person INNER JOIN address ON persion.id=address.id");
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("City"));
Now, you can use this 2D model wherever you need. Also you can use a QDataWidgetMapper with this model in order to share its data with multiple widgets.

Related

Use QAbstractProxyModel to add extra "virtual" columns in a table

I have some data which are stored in a variable "myStorage" (a QVector).
I use a QAbstractTableModel to display these data in a QTableView : each entry in the QVector is a row in the table and each field in "myStruct" is a column.
Now I want to display more information, in a new column, without any modification to "myStruct" or to my model.
So I tried to make a new model class, derived from QAbstractProxyModel, which should add the new "virtual" column.
(For example, this column could be the average of 2 existing fields in "myStruct")
But I can't make it work : in the worst case, the program crash, in the best case, I have the right number of columns (one more than in the proxied model) and the right headers, but the data are shifted and the last column is empty.
Is there any minimal/simple example of a "add virtual column proxy model" working implementation ?
Should I use QIdentityProxyModel as a base class instead of QAbstractProxyModel ?
Thanks

Qt display not all fields from Model

I'm displaying the query from an QSqlModel in a table view. e.G.
SELECT id, name FROM person;
I don't want to display id in the view, however I need the id when the user clicks on a row in that view.
Is there a model in Qt, which allows me to display only specified columns in views but also providing access to invisible ones?
I used to do it by hiding the columns e.g.:
ui->myview->setColumnHidden( 0, true );
But probably there is a better solution.
Since the OP amended the question to exclude using QTableView the only alternative that would seem to work is the creation of a new class derived from QSortFilterProxyModel. One can override the filterAcceptsColumn method
Documentation on the class QSortFilterProxyModel can be found here
QSortFilterProxyModel can be used for sorting items, filtering out items, or both. The model transforms the structure of a source model by mapping the model indexes it supplies to new indexes, corresponding to different locations, for views to use. This approach allows a given source model to be restructured as far as views are concerned without requiring any transformations on the underlying data, and without duplicating the data in memory.
You'd also have to override MapToSource and SourceToMap . There is a good example of usage in this StackOverflow's answer

Qt: QSqlTableModel + QTableView sync with PostgreSQL

I'm writing a database access app for storing some data and want to ask a few questions about the model/view architecture.
(Using: Qt 4.7.4, own build; PostgreSQL 9.0; Targets: WinXP, Win7 (32/64 bit))
Let me first explain what I am trying to achieve and where I am currently.
I have two pages (subclassed QWidgets inserted in a QStackedWidget) with a QTableView bound to a model. Each view is bound to a table in the PostgreSQL server. You can add/edit/delete/sort/filter items.
Each page can be seen by only one type of users, lets call the roles Role1 and Role2.
The submit strategies of everything connected to the model are OnManualSubmit.
(Transaction isolation level = Serializable.) When two users want to edit(for example) the same row, I want to do a "SELECT ... FOR UPDATE" query - to make sure that when someone edits something, he will merge his changes with newer ones (if any, just like in SVN for example). But I see only a submitAll() method the QSqlTableModel.
Maybe catching the signals beforeUpdate(), beforeDelete(), beforeInsert() and performing manually "SELECT ... FOR UPDATE" is one option.
The other way I think is to subclass QSqlTableModel. What is the clean and nice way to achieve this?
I want to periodically update the QSqlTableView for each of the pages (one page is seen at most, Role1 users have access only to Page1 and the same for Role2 => Page2).
The first thing that came to my mind is to use a QTimer and manually call select() of the QSqlTableModel, but... not sure if this is the cool way.
I also want to periodically check if the connection to the database is ok, but I think that a QTimer + QSqlDatabase::isOpen () will do.
Now, the 2 tables have the same primary keys and some columns are the same. I want when a user with Role1 changes a row in Table1 to automatically change corresponding columns of Table2 and vice versa. Should I create a trigger in Postgres?
BTW, the database is small - each of the two tables is around 3-4000 rows with ~10 columns (varchars mostly, 1 text and 2 date colunms).
Thanks for reading and Happy New Year! :)
I think you should consider doing something of the following:
Instead of using QSqlTableModel as a model I'd implement my own model as a subclass of QAbstractTableModel. This will allow you a lot of control over what you can do in terms of data manipulation.
One thing that this will require is for certain fields in the table you would need to implement subclass of QAbstractItemDelegate that will allow for modification of data in the table as I am fairly sure you don't want to allow users updating any field in the table as for example primary key is likely have to be left alone.
For question 2 I would suggest implementing a field called transaction_counter for every row so you don't have to select every row in the table just the updated ones the transaction_counter will be updated on every row update and the new one will be inserted on the new row insert. One thing that will be required is that the counter is unique across the table. For example if initial state of the table is: row1 has counter = 0 and row2 has counter = 0. If row1 is updated counter set to 1. When row1 is then updated again counter on it is set to 2. When row2 is now updated counter on it is set to 3, etc. You can certainly do the data refreshes now using QTimer and this will be much more advantageous to for example checking the data as one user may be updating the same table as another user with the same Role.
For Question 3. I don't see any reason why not custom models and especially if you decide to separate data from the model you can manipulate data separately from it's display. Sort of Data->Model->View->Controller implementation. Each one can be maintained separately as long as you have a feedback mechanism for your delegates.
For Question 4. The answer is sure or you can implement the trigger in your application.
Hope this helps. Have a great New Year!

Drupal create views involving LEFT JOIN Sub-Select with non-existent node

i'm using Drupal 6
I have this table relation and I've translated into CCK complete with it's relation.
Basically when I view a Period node, I have tabs to display ALL Faculty nodes combined with Presence Number.
here's the table diagram: http://i.stack.imgur.com/7Y5cU.png
Translated into CCK like these:
CCK Faculty (name),
CCK Period (desc,from,to) and
CCK Presence(node-reference-faculty, node-reference-period, presence_number)
Here's my simple manual SQL query that achieve this result: http://i.stack.imgur.com/oysd3.png
SELECT faculty.name, presence.presence_number FROM Faculty AS faculty
LEFT JOIN (SELECT * FROM Presence WHERE Period_id=1) AS presence ON faculty.id=presence.Faculty_id
The value of 1 for Period_id will be given by the Period Node ID from the url argument.
Now the hardest part, is simulating simple SQL query above into Views. How can I make such query into Views in Drupal-6 or Drupal-7 ?
thanks for any helps.
The main issue, which I think you've noticed, is that if you treat Faculty as the base for your join, then there is no way to join on the Presence nodes. Oppositely, if you treat Presence as the base, then you will not see faculties that have no presence number.
There is no easy way, using your currently defined structure, to do these joins in views.
I would say your easiest option is to remove the 'node-reference-faculty' field from the presence node and add a node-reference-presence field to the faculty. Since CCK fields can have multiple values, you can still have your one-to-many relationship properly.
The one downside of this is that then you need to manage the presence-faculty relationship from the faculty nodes instead of the presence nodes. If that's a show stopper, which it could be depending on your workflow, you could have BOTH node-reference fields, and use a module like http://drupal.org/project/backreference to keep them in sync.
Once you have your reference from faculty -> presence, you will need to add a relationship in Views. Just like adding a field or a filter, open the list of relationships and find the one for your node-reference field.
Next, you will need to add an argument for period id and set it up to use a node id from the url. The key thing is that when you add the argument, it will ask which relationship to use in its options. You will want to tell it to use your newly added presence relationship.
You don't really need to do a subquery in your SQL like that. This should be the same thing and won't make mysql try to create a temporary table. I mention it because you can't really do subqueries in Views unless you are writing a very custom Views handler, but in this case you don't really need the subquery anyway.
Ex.
SELECT f.name, p.presence_number
FROM Faculty AS f
LEFT JOIN Presence AS p ON f.id=p.Faculty_id
WHERE p.Period_id=1;
I wrote an article about how to achieve a similar outcome here. http://scottanderson.com.au/#joining-a-views-query-to-a-derived-table-or-subquery
Basically how to alter a Views query to left join on a sub-query.

Qt – How to add calculated column in QsqlRelationalTableModel?

I have an table view showed
part description, quantity, price
And I have a Model/View using this code
model = new QSqlRelationalTableModel(this);
model->setTable("parts");
model->setRelation(3,QSqlRelation("part_tbl","part_id","part_desc"));
model->select();
ui->tableView->setModel(model);
I need to add a new column that shows quantity * price in the table view. It's important to know I'm using QsqlRelationalTableModel
Help is appreciated, Thanks in advance
I think your best bet for handling this is to make either a model that inherits QSqlRelationalTableModel, or one that acts as a proxy (and contains a member for the model). Your new model will add the extra column, and when the data is requested for that column, use the data from the other columns to compute what is required.

Resources