Results 1 to 4 of 4

Thread: multiple QDataWidgetMapper's tied to one model causes index to be reset

  1. #1
    Join Date
    May 2006
    Posts
    70
    Thanks
    12
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default multiple QDataWidgetMapper's tied to one model causes index to be reset

    I'm struggling with getting two QDataWidgetMapper's that are tied to a single model to work properly.

    This is the code I have:
    Qt Code:
    1. MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    2. {
    3. setupUi(this);
    4.  
    5. //Create the model
    6. _myModel = new QSqlTableModel(this);
    7. _myModel->setTable("mytable");
    8. _myModel->setEditStrategy(QSqlTableModel::OnRowChange);
    9. _myModel->select();
    10.  
    11. //Create the first mapper
    12. _myFirstMapper = new QDataWidgetMapper(this);
    13. _myFirstMapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    14. _myFirstMapper->setModel(_myModel);
    15. _myFirstMapper->addMapping(myFirstEdit, 0);
    16. connect(_myFirstMapper->itemDelegate(), SIGNAL(commitData(QWidget*)),
    17. this, SLOT(saveMyFirstData()));
    18.  
    19. //Create the second mapper
    20. _mySecondMapper = new QDataWidgetMapper(this);
    21. _mySecondMapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    22. _mySecondMapper->setModel(_myModel);
    23. _mySecondMapper->addMapping(mySecondEdit, 0);
    24. connect(_mySecondMapper->itemDelegate(), SIGNAL(commitData(QWidget*)),
    25. this, SLOT(saveMySecondData()));
    26.  
    27. //Jump to the same row for each mapper
    28. _myFirstMapper->toFirst();
    29. _mySecondMapper->toFirst();
    30. }
    31.  
    32. void saveMyFirstData() {
    33. int current = _myFirstMapper->currentIndex();
    34. _myFirstMapper->submit();
    35. _myFirstMapper->setCurrentIndex(current);
    36. }
    37.  
    38. void saveMySecondData() {
    39. int current = _mySecondMapper->currentIndex();
    40. _mySecondMapper->submit();
    41. _mySecondMapper->setCurrentIndex(current);
    42. }
    To copy to clipboard, switch view to plain text mode 

    Now, I connect the itemDelegate's signal to those slots because it was the only way I could use the QDataWidgetMapper with the ManualSubmit policy. The AutoSubmit policy did not work at all no matter what I tried.

    What happens is when I change the value in "myFirstEdit" the second mapper gets it's currentIndex reset to -1. The reason is because the call to _myFirstMapper->submit() actually calls myModel->submit() which has the effect of resetting all QDataWidgetMappers attached to that model to -1. Why, I don't know.

    Now the obvious correction to my code above is to have only one save slot like this:
    Qt Code:
    1. void saveMyData() {
    2. int currentFirst = _myFirstMapper->currentIndex();
    3. int currentSecond = _mySecondMapper->currentIndex();
    4. _myFirstMapper->submit();
    5. _mySecondMapper->submit();
    6. _myFirstMapper->setCurrentIndex(currentFirst);
    7. _mySecondMapper->setCurrentIndex(currentSecond);
    8. }
    To copy to clipboard, switch view to plain text mode 

    Now here's my problem, what happens if the two different QDataWidgetMapper's are on separate forms that have no idea about each other, but they still use the same model. If I save data on the second form the first form's mapper's index gets set to -1.

    Is this a bug in Qt or am I misunderstanding how to use QDataWidgetMapper?

    And yes, I'd love for the AutoSubmit policy to work but it just plain doesn't work. At least not for me and the other people that had the same problem and suggested doing that signal slot connection.

    Thanks, Mike

  2. #2
    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: multiple QDataWidgetMapper's tied to one model causes index to be reset

    Quote Originally Posted by darkadept View Post
    Is this a bug in Qt or am I misunderstanding how to use QDataWidgetMapper?
    No, it's a feature of the SQL model. When you submit changes to the SQL model, it gets reset and all views (including all data mappers) along with it. It's just the way it is - the model has to refresh itself completely. You mustn't use OnRowChange edit strategy, because that will trigger a submit upon every change. Use OnManualSubmit and submit the data manually once just before the model dies.

  3. #3
    Join Date
    May 2006
    Posts
    70
    Thanks
    12
    Thanked 4 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: multiple QDataWidgetMapper's tied to one model causes index to be reset

    Ok. That makes sense.

    Now you say "just before the model dies". I'm wondering, what is a good lifetime for a model to "live"? Are models meant to be short lived or long? The QSqlTableModel's I'm using are loaded at first use and then kept alive until the program quits. Is that bad practice?

    For long lived models I can pass the row (or index) around as long as I don't store it (I'd use persistant indexes for that). That seems very efficient to me. For short lived models I'd have to pass an Id value and use a filter to select my data each time. Is that just as good?

    I'd also run into sync problems if I have two QSqlTableModels that select the same data being used in different parts of the program. Or am I wrong?

  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: multiple QDataWidgetMapper's tied to one model causes index to be reset

    Quote Originally Posted by darkadept View Post
    Is that bad practice?
    It's fine. You may even subclass the model and reimplement its destructor to submit the data.

    I'd also run into sync problems if I have two QSqlTableModels that select the same data being used in different parts of the program. Or am I wrong?
    Use the same model.

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.