Results 1 to 14 of 14

Thread: Help with Model View

  1. #1
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Question Help with Model View

    Hye all,

    I'm developing an application with PyQt (I do not think it's the problem), and I've got some little problem with my model and my views.

    I've got 1 model with 3 view on QSortFilterProxyModel that point on my model.
    Some point on a specific node of the global model ("setRootIndex").

    My problem is that when i want to add a new row in my model (I use "beginInsertRows" and "endInsertRows") it work not exactly well; row are properly inserted, but all my windows lost there RootIndex.

    Does any of you know how to manage it ?

  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: Help with Model View

    Could you show us your implementation of insertRow()?

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

    weepdoo (12th October 2007)

  4. #3
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    As I said, I'm codinf with PyQt, so it's python:
    Qt Code:
    1. def newFromIndex(self, index):
    2. """
    3. @param index: the index wanted
    4. @type index: QModelIndex
    5. """
    6. self.beginInsertRows(index, self.rowCount(index), self.rowCount(index))
    7.  
    8. node = self.getNodeFromIndex(index)
    9. newNode = node.new()
    10. newIndex = self.getIndexFromNode(newNode)
    11.  
    12. self.endInsertRows()
    13. return newIndex
    To copy to clipboard, switch view to plain text mode 

    I do not use "insertRow" because I have two different case where I have to inser a new row (new and duplicate).

  5. #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: Help with Model View

    This code doesn't say much... What does node.new() exactly do? Does it insert the new node into some internal structure? You are inserting the new node as a child of the old node, correct?

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

    weepdoo (12th October 2007)

  7. #5
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    Yes
    Ok, I going to give a bit more explanation :P

    My data struct is has this:
    Qt Code:
    1. root
    2. |-A
    3. |-S
    4. |-E
    To copy to clipboard, switch view to plain text mode 

    The 'new' method applied on the node 'A' and produce the result:
    Qt Code:
    1. root
    2. |-A
    3. |-S
    4. | |-E
    5. |-New S
    To copy to clipboard, switch view to plain text mode 

    So, the method "newFromIndex" get the index of 'A' create a 'New S' and return.
    The new node is added as the last child (that why I use "rowCount(index)").

    The two method "getNodeFromIndex" and "getIndexFromNode" are just two method to make the link from a QModelIndex and my data. But they do not modifiy anything in my data.

  8. #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: Help with Model View

    You could get rid of those two methods you know... Each model index can contain an internalPointer() or internalId() that you can tie to your datastructure. Then you can just query for that value and access your node directly.

    Honestly I can't see anything wrong with your code. Could you show the part of code responsible for calling that method?

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

    weepdoo (11th October 2007)

  10. #7
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    Ok...
    It's going to be a bit long here, but I'll try.

    I've got a main window that can manipulate many sort of data (so many different models), and if we change the current type of data, it change the model, mainwindow menu etc... well quiet classic in fact.
    There is a qWorkSpace, and different windows in it

    Here is the init off the QAction button for the 'new':
    Qt Code:
    1. self._dActions["actionDocNew"] = QtGui.QAction(self._parent)
    2. self._dActions["actionDocNew"].setObjectName("actionDocNew")
    3. self._dActions["actionDocNew"].setText(_(u"New"))
    4. self._dActions["actionDocNew"].setEnabled(False)
    5. QtCore.QObject.connect(self._dActions["actionDocNew"],
    6. QtCore.SIGNAL('activated()'),
    7. self._newDoc)
    To copy to clipboard, switch view to plain text mode 
    All actions are stored in a dictionnary (=hasTable) called "dActions" (_ before 'means' protected in python)

    Here is the code for the 'new' action
    Qt Code:
    1. def _newDoc(self):
    2. index = self._mainWindow.currentIndex
    3. # If the index is not correct we do nothing
    4. if not index:
    5. return
    6. #This is my call to the model (as I showed it to you befiore)
    7. newIndex = self._mainWindow.currentModel.newFromIndex(index)
    8.  
    9. # Now we edit the properties of the new index
    10. # Even If I unable this call, I've got my problem
    11. self._properties(newIndex)
    To copy to clipboard, switch view to plain text mode 

    In my child Windows (that display different part of the model as the node 'E') I link with the model as this.
    They all inherit from QWidget (not from QAbstractItemView because some part of my widget are not linked to the model).
    self.ui <- subobject where all view / widget are
    self.ui.treeView <- a simple QTreeView
    Qt Code:
    1. def setModel(self, model, globalRootIndex=None):
    2. # We use a proxy, and not the model
    3. self._proxy = QtGui.QSortFilterProxyModel()
    4. self._proxy.setSourceModel(model)
    5.  
    6. #We link the treeView (used in this widget) and the proxy model
    7. self.ui.treeView.setModel(self._proxy)
    8.  
    9. # We set the correct tree root
    10. proxyRootIndex = self._proxy.mapFromSource(globalRootIndex)
    11. self.ui.treeView.setRootIndex(proxyRootIndex)
    12.  
    13. # We add the delegate, to manage event
    14. self.ui.treeView.setItemDelegate(self._delegate)
    To copy to clipboard, switch view to plain text mode 

  11. #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: Help with Model View

    Could you create an additional small object that would connect to signals layoutChanged, modelReset and rowsInserted of the model and report when they are emited? Then you can trace what exactly happens when you insert an item to the model.

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

    weepdoo (12th October 2007)

  13. #9
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    Ok, I've changed a bit my model:

    Here is how I init it
    Qt Code:
    1. class Model(QtCore.QAbstractItemModel):
    2. def __init__(self, qtgDoc, parent=None):
    3. super(QtgModel, self).__init__(parent)
    4. #======= Attributes Declaration =========
    5. [...] # <- We do not care this
    6.  
    7. self.modelLoger = modelLoger(self) # <- the "listener" of the model
    8. #========================================
    9.  
    10. #We test our listener :)
    11. self.emit(QtCore.SIGNAL("layoutChanged()"))
    To copy to clipboard, switch view to plain text mode 

    Here is the code of our listener
    Qt Code:
    1. class modelLoger(object):
    2. def __init__(self, model):
    3. connect = QtCore.QObject.connect #We create a shortcut to the function (easiest :P)
    4.  
    5. connect(model,
    6. QtCore.SIGNAL('layoutChanged()'),
    7. self.layoutChanged)
    8.  
    9. connect(model,
    10. QtCore.SIGNAL('modelReset()'),
    11. self.modelReset)
    12.  
    13. connect(model,
    14. QtCore.SIGNAL('rowsInserted(const QModelIndex &, int , int)'),
    15. self.rowsInserted)
    16.  
    17. def layoutChanged(self):
    18. print time.strftime("%H:%M:%S"), "layout Changed"
    19.  
    20. def modelReset(self):
    21. print time.strftime("%H:%M:%S"), "modelReset"
    22.  
    23. def rowsInserted(self):
    24. print time.strftime("%H:%M:%S"), "rowsInserted"
    To copy to clipboard, switch view to plain text mode 

    Here is the output I have (I only launch the application, make a new 'S' under 'A' and quit) :
    Qt Code:
    1. 14:19:35 layout Changed # <- the test in the __init__ of the model
    2. 14:19:39 rowsInserted # <- we create the new 's'
    3. #<- we quit :)
    To copy to clipboard, switch view to plain text mode 

    Thanks for your time

  14. #10
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Thumbs up Re: Help with Model View

    Quote Originally Posted by wysota View Post
    You could get rid of those two methods you know... Each model index can contain an internalPointer() or internalId() that you can tie to your datastructure. Then you can just query for that value and access your node directly.
    I really doubted it could work.
    Because, when we use "createIndex" we do it like this:
    Qt Code:
    1. self.createIndex(row, column, id(node))
    To copy to clipboard, switch view to plain text mode 

    Where 'id' is a built in function, that return a unique number of the object (quiet like a pointer in C++). From the python documentation: This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime

    But in Python, we always use reference on object, and there is (as far as I know) no way to get the object when you have his address in memory (nor his 'id').

    That why I have to create my own methods.

    But I've tested your method, and it work just great
    Thanks to you
    Last edited by weepdoo; 11th October 2007 at 15:00.

  15. #11
    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: Help with Model View

    Quote Originally Posted by weepdoo View Post
    Here is the output I have (I only launch the application, make a new 'S' under 'A' and quit) :
    Qt Code:
    1. 14:19:35 layout Changed # <- the test in the __init__ of the model
    2. 14:19:39 rowsInserted # <- we create the new 's'
    3. #<- we quit :)
    To copy to clipboard, switch view to plain text mode 
    That's not good. I was hoping to receive a faulty modelReset() or similar signal that might have caused the views to malfunction, but nothing like that happens. Could you check what happens if you remove the proxies from the model? Does the root index still malfunction?

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

    weepdoo (12th October 2007)

  17. #12
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    I've change my windows code to do not use a proxy, and I do not have the problem

    Must I "reset" the rootIndex in the proxy ?

  18. #13
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Help with Model View

    I've use the same object logger as before on my proxy, and when I inser a new row, with 3 view opened I've got this:
    Qt Code:
    1. 10:45:30 rowsInserted # <- I inser the row
    2. 10:45:30 layout Changed # <-|
    3. 10:45:30 layout Changed # <-|- The three view have their layout changed
    4. 10:45:30 layout Changed # <-|
    To copy to clipboard, switch view to plain text mode 

    Should I use this signal to reset the root index to the view ?

  19. #14
    Join Date
    Jul 2006
    Location
    France
    Posts
    34
    Thanks
    12
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Thumbs up Re: Help with Model View

    I've catch the signal (layoutChanged) and reset the root Index to the correct value, and I must confess that it work well

    Thank for your help wysota

Similar Threads

  1. hierarchical model in a flat view
    By gniking in forum Qt Programming
    Replies: 4
    Last Post: 10th November 2009, 21:17
  2. Model, View and Proxy
    By No-Nonsense in forum Qt Programming
    Replies: 2
    Last Post: 21st November 2006, 09:50
  3. Should I develop my own model and view?
    By dandanch in forum Qt Programming
    Replies: 1
    Last Post: 20th November 2006, 07:09
  4. Model - View Programming doubt.
    By munna in forum Qt Programming
    Replies: 4
    Last Post: 28th April 2006, 14:01
  5. Replies: 6
    Last Post: 20th April 2006, 11:23

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.