Results 1 to 13 of 13

Thread: Best way to pass data between child's model and parent ?

  1. #1
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    Hello!

    I have a invoice-form which opens a addressbook to select a customer. Both are bound to a SQL-database using QSqlTableModel.

    The selected customer should be written into some QLineEdits within the invoice-form.

    The addressbook's selection model is working fine, but I wonder which is the best way to pass the selected row (the customer) to its parent if a pushButton sending the accept()-signal is clicked.

    I thought about passing a QModelIndex somehow, but the Qt API Doc says that QModelIndex should be proccessed on the spot.

    Qt Code:
    1. QModelIndex index = tableView->currentIndex();
    To copy to clipboard, switch view to plain text mode 

    Another possibility would be to pass a QSqlRecord like this:

    Qt Code:
    1. QSqlRecord record = modelCustomer->record(index.row());
    To copy to clipboard, switch view to plain text mode 

    I am not only unsure about the container to pass the data in, also I don't know if its better to send the data via a signal or to interact on the accept()-signal from parent-side like

    Qt Code:
    1. if (selectCustomer->exec())
    2. {
    3. selectCustomer->doSomeThing...
    4. }
    To copy to clipboard, switch view to plain text mode 

    I hope you have some good advice for me.

    Kind regards,
    HomeR


    Added after 1 58 minutes:


    After reading here in the forum for a while I decided to use a getter-function like

    Qt Code:
    1. if (selectCustomer->exec())
    2. {
    3. selectCustomer->doSomeThing...
    4. }
    To copy to clipboard, switch view to plain text mode 

    But which data should I pass? An SQL-record? An index?
    Last edited by homerun4711; 6th January 2011 at 16:13.

  2. #2
    Join Date
    Nov 2010
    Posts
    97
    Thanks
    6
    Thanked 11 Times in 11 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Best way to pass data between child's model and parent ?

    I don't know what you're trying to do and what's the "best thing" (it's all opinion anyway) is so much dependent upon what you're trying to do. I'll try to provide some help anyway but it's probably going to be limited.

    First thing I note is the warning in the documentation:

    Note: Model indexes should be used immediately and then discarded. You should not rely on indexes to remain valid after calling model functions that change the structure of the model or delete items. If you need to keep a model index over time use a QPersistentModelIndex.
    So it, first of all, looks like you have an answer if you need the index: QPersistentModelIndex.

    Second of all, it looks like the, "...ModelIndex should be used immediately...," warning is for exactly the reason I expect: it can become invalid if the model changes. In a multi-threaded environment it would thus be very difficult to pass a ModelIndex out of your model. You'd need to lock the model up so it couldn't be modified until processing of that index was accomplished. If you're not using MT then you probably have less to worry about and passing the ModelIndex directly to whatever might work just fine. But a) you shouldn't take shortcuts that kill a future decision (I want to MT now) without good reason, and b) you have a "right" way to do it.

    Next, I have a feeling that what you're doing might not be best anyway. There might not be a best answer to, "How do I send the data to the parent," because the question itself might be based on a flawed method. I really try to get as much of the model manipulation logic as possible into that model. I like to think of my models as encapsulated boxes that spit out domain data (meaning data specific to the problem, not model indexes or whatnot). A button press that then does something to the model may very well be best handled by the model itself. It's hard to say if this is right and it would be hard to say HOW I would do it in your case without knowing your problem intimately.

    My *guess* at what might be best for you is the SQL record data. If that's enough for the thing to do its job, that's what you should send.
    This rude guy who doesn't want you to answer his questions.

    Note: An "expert" here is just someone that's posted a lot.

    "The fact of where you do the encapsulation is meaningless." - Qt Certified Developer and forum moderator

  3. #3
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    My *guess* at what might be best for you is the SQL record data. If that's enough for the thing to do its job, that's what you should send.
    Thanks for your answer. Perfect, thats what I chose to try. Here is what I wrote:

    Qt Code:
    1. if (customerSelect->exec())
    2. {
    3. QSqlRecord record = customerSelect->passRecord();
    4. ...
    5. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. QSqlRecord SelectAddress::passRecord()
    2. {
    3. QModelIndex index = tableView->currentIndex();
    4. QSqlRecord record = modelCustomer->record(index.row());
    5. return record;
    6. }
    To copy to clipboard, switch view to plain text mode 

    It's working fine.

    Can you help me with another quick question:

    I would like to assign a customer number to every entry in the customer-database. It should be a concatenation of a Prefix, e.g. "C" and a number.
    As number I would like to use either the number of rows (means customers) in the database or the PrimaryKey for that row.

    Do you know how I can access the primary key for the row, or the highest primary key?

    So far I found two possibilities, but maybe there are "cleaner" ones.

    1.) The number of entries ist listed in a special table for SQLite databases, read the value from there:

    Qt Code:
    1. QSqlQuery query("SELECT * FROM sqlite_sequence");
    2. int fieldNo = query.record().indexOf("seq");
    3.  
    4. while (query.next()) {
    5. QString rows = query.value(fieldNo).toString();
    6. out << "rows: " << rows << "\n";
    7. }
    To copy to clipboard, switch view to plain text mode 

    2.) List the all customer entries and read the number of lines using query.size() or just count them using a loop.

    Qt Code:
    1. QSqlQuery query("SELECT * FROM customers");
    2. int rows = query2.size();
    To copy to clipboard, switch view to plain text mode 

    But using size() always returns -1, I found out right know that's because SQLite does not support size().

    Are there other possibilities?

    But both methods are not working if rows have been deleted...

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Best way to pass data between child's model and parent ?

    You should really learn a bit about databases before tackling with such a subject. Relational databases have a concept of auto incrementing fields or sequences (depending on the database) that are used for assigning primary key values automatically. Read this: http://www.sqlite.org/autoinc.html
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    Do you know how I can access the primary key for the row, or the highest primary key?
    Maybe I was not clear enough. I am familiar with the concepts of primary keys and auto-incrementing . I do not want to write / set this key, I just want to read it to assign an unique customerID to each customer (a new, non-autoinc column), I just have to read the primary key.

    SQLite keeps track of the largest ROWID that a table has ever held using the special SQLITE_SEQUENCE table. The SQLITE_SEQUENCE table is created and initialized automatically whenever a normal table that contains an AUTOINCREMENT column is created.
    So maybe the best would be to use that value + 1 to assign a customerID (Prefix + MAX(autoinc)). But since this is limitied to SQLite, I thought it might be better to use a more common method to be able to change the database-type afterwards.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Best way to pass data between child's model and parent ?

    Based on what you write here I can state you are not familiar with what yo claim to be familiar with. The id of a customer is a primary key of the customer table (your "C" prefix is completely unnecessary in the database, you can have it in your program to show it to your users but don't place it in the database) so you don't assign the numbers yourself but rather let the database do it by using an auto incrementing primary key. After you have inserted a new customer to the database you can ask the database about the last inserted row using QSqlQuery::lastInsertId(). If the database doesn't support it (sqlite should but anyway...) then you can always ask for the highest id in the table (SELECT MAX(id) from customers) and unless you messed with id manually, that will be the id you are looking for.

    Please save yourself the effort and don't reinvent the wheel at every step - learn more about database programming before doing something on your own.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    homerun4711 (7th January 2011)

  8. #7
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    QSqlQuery::lastInsertId(), table (SELECT MAX(id) from customers)
    Thank you for the suggestions, this was the information I was looking for. I do not want to use the customerID to count something or as a primary key. It just will be a QString concatenated of a changeable prefix and the primary key (to make the customerID-number-part unique, independently of the prefix).

  9. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Best way to pass data between child's model and parent ?

    Quote Originally Posted by homerun4711 View Post
    Thank you for the suggestions, this was the information I was looking for. I do not want to use the customerID to count something or as a primary key. It just will be a QString concatenated of a changeable prefix and the primary key (to make the customerID-number-part unique, independently of the prefix).
    That's not a good idea. Make the prefix a separate field (if at all), don't concatenate the two in the database. The primary key is your real customer id, regardless of what you show to your users. You should always associate the primary key with customer fields in other tables and not your concatenation because this will lead to more trouble and is likely to trash your whole database. Primary key is the only value that can (logically) never change during the whole lifetime of the database. Unless you are planning on allowing your users to manually input or change "customer id" of a particular customer to something completely custom (like "my friend joe" instead of "C01234") the primary key is sufficient. And even if you plan to do that, you can have an "alias" field that can be null or can contain a custom string ("my friend joe") but you will still refer to him in the database as "1234" and not "my friend joe". Otherwise if you rename "my friend joe" to "my ex-friend joe" some day then you will lose all the data from the database related to your customer (because in other tables you will still have "my friend joe" as the customer id).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. #9
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    You should always associate the primary key with customer fields in other tables and not your concatenation because this will lead to more trouble and is likely to trash your whole database.
    Yes, I am aware of that and I will for sure only use the primary key for QSqlRelationalTableModels and joins to achieve a reliable database. The concatenation is only a QString to display on the pdf- or print-version of an invoice, but it will also be unique.

  11. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Best way to pass data between child's model and parent ?

    Quote Originally Posted by homerun4711 View Post
    The concatenation is only a QString to display on the pdf- or print-version of an invoice, but it will also be unique.
    Since the prefix will always be the same for every client what is the point in keeping it in every record of the database? What if some day you decide to change the prefix?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #11
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    What if some day you decide to change the prefix?
    This is even an wanted option. The user should be able to change the prefix if he wants to use another format (this is an wanted option). But to be consistent with invoices that have been send as letters or pdfs, I have to keep the customer number (prefix + number ) inside the database.
    The customer number will be unique and fixed to that customer, even if the prefix does change later, it will not change for customers created before a new prefix was used. (C0001, Cst0002, CNo0003)

  13. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Best way to pass data between child's model and parent ?

    Quote Originally Posted by homerun4711 View Post
    This is even an wanted option. The user should be able to change the prefix if he wants to use another format (this is an wanted option). But to be consistent with invoices that have been send as letters or pdfs, I have to keep the customer number (prefix + number ) inside the database.
    The customer number will be unique and fixed to that customer, even if the prefix does change later, it will not change for customers created before a new prefix was used. (C0001, Cst0002, CNo0003)
    What's the point of the prefix then? Anyway, don't concatenate, keep the prefix as a separate field. This gives you more flexibility. And if you want to do the concatenation then do it in the server - create a trigger that will automatically fill the "customer id" column based on the current prefix and the primary key.

    http://www.sqlite.org/lang_createtrigger.html
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. The following user says thank you to wysota for this useful post:

    homerun4711 (7th January 2011)

  15. #13
    Join Date
    Oct 2010
    Posts
    91
    Thanks
    38

    Default Re: Best way to pass data between child's model and parent ?

    What's the point of the prefix then?
    Just to keep the numbers for customers and invoices printed on the invoices clearly different.

    Anyway, don't concatenate, keep the prefix as a separate field. This gives you more flexibility.
    Ok, this is a very good idea. Thanks for that.

Similar Threads

  1. Replies: 11
    Last Post: 14th March 2010, 22:00
  2. Parent Child for window
    By febil in forum Qt Programming
    Replies: 6
    Last Post: 1st April 2009, 05:00
  3. Connecting child and parent
    By maverick_pol in forum Qt Programming
    Replies: 17
    Last Post: 17th July 2007, 08:11
  4. resizeEvent from parent to child?
    By ChasW in forum Qt Programming
    Replies: 3
    Last Post: 11th February 2007, 18:21
  5. Parent-child-problems ;)
    By nupul in forum Qt Programming
    Replies: 11
    Last Post: 9th May 2006, 14:03

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.