Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Describe an algorithm using signals/slots together with ItemChildAdded/RemovedChange that will know when to clear its memo (complex graph) i.e. when it's done?
Qt 6.11 is out! See what's new in the release blog

Describe an algorithm using signals/slots together with ItemChildAdded/RemovedChange that will know when to clear its memo (complex graph) i.e. when it's done?

Scheduled Pinned Locked Moved Solved General and Desktop
2 Posts 1 Posters 264 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • enjoysmathE Offline
    enjoysmathE Offline
    enjoysmath
    wrote on last edited by enjoysmath
    #1

    80cf4a9d-d2b6-47eb-99b5-be810efeaaa5-image.png

    I have a quite complicated question to ask here. Node labeled C is a DirectedGraph. The arrow labeled G is a Directed graph morphism.

    Now I'm currently doing this using signals/slots insided of GraphMorphism:

    def take_image(self):
            if self.dom() is None or self.cod() is None:
                raise Exception("Both domain and codomain must be set before calling GraphMorphism.take_image().")
    
            for X in self.dom().nodes():            
                if id(X) not in self._domainNodes:
                    self._domainNodes[id(X)] = X
                    FX = X.copy()
                    self.cod().add_node(FX)
                    FX.setPos(X.pos())
                    self._codomainNodes[id(FX)] = FX
                    self._imageMap[id(X)] = id(FX)
                    X.position_changing_memoized.connect(lambda delta, memo: self._onItemPositionChange(FX, delta, memo))
                    FX.position_changing_memoized.connect(lambda delta, memo: self._onItemPositionChange(X, delta, memo))
            
            for A in self.dom().arrows():
                if id(A) not in self._domainArrows:
                    FA = A.copy()
                    self.cod().add_arrow(FA)
                    FA.setPos(A.pos())
                    FA.label_item().setPos(A.label_item().pos())
                    FA.set_label(A.label())
                    FA.set_source(self._codomainNodes[self._imageMap[id(A.source())]])
                    FA.set_target(self._codomainNodes[self._imageMap[id(A.target())]])                
                    self._domainArrows[id(FA)] = FA
                    self._imageMap[id(A)] = id(FA)
                    for k, point in enumerate(A.control_points()):
                        FA.setPos(point.pos())
                        if k in {1, 2}:
                            point.position_changing_memoized.connect(
                                lambda delta, memo, point=FA.control_points()[k]: self._onItemPositionChange(
                                    point, delta, memo))                        
                    FA.update()
                                    
            self._imageTaken = True
    

    The result is that one can reflect position changes of the corresponding nodes arrows (between the graphs) in either direction, without the obvious bug of infinite recursion. Infinite recursion occurs naturally because a setPos() on a domain node (a node in C) will setPos() on its corresponding node in D, and in turn that will cause a setPos() in C again, and so on... But there is also infinite loops formed when a loop in the graph of GraphMorphisms is formed. That is because I am allowing loops in these graphs (they are not DAG's in general).

    However, I am determining when to clear the memo (held in each item: _posChangingMemo : set) which holds each visited item's id() (like it's instance pointer in Python), solely when the user does a mouseReleaseEvent() on the item being moved. Obviously this will cause the bug of if the scene gets cludgy, then mouseReleaseEvent() might be called too early, clearing the memo before the chain of signal/slot calls has propogated to everywhere it needs to go.

    However, it is currently working with the depicted example. Another thing I want reflected by GraphMorphisms/Functors is when I add/remove a node, it will automatically propogate, but I cut off this propogation when when the GraphMorphisms form a loop. Ie. I propogate just one time around. I can see bugs forming with this as well. My first question is where would be a good spot to clear the memo? Again, each involved item holds a reference to a common _addingChildMemo (resp. _removingChildMemo:set). They are assigned like so:

    def setPos(self, pos: QPointF, memo: set = None):
           if pos != self.pos():        
               if memo is None:
                   memo = set()
                   
               if id(self) not in memo:
                   if len(self._posChangingMemo) > 0:
                       self._clearPosChangingMemos()                
                   self._posChangingMemo = memo
                   delta = pos - self.pos()
                   memo.add(id(self)) 
                   self.position_changing_memoized.emit(delta, memo)                                            
                   super().setPos(pos)
    

    The signals/slots approach seems very flimsy/buggy. Can you suggest another approach? Thanks.

    https://github.com/enjoysmath
    https://math.stackexchange.com/users/26327/exercisingmathematician

    1 Reply Last reply
    0
    • enjoysmathE Offline
      enjoysmathE Offline
      enjoysmath
      wrote on last edited by
      #2

      I think I've got it, I look at the parent container's arrows (BigCat's arrows). Anything connected to the nodes I'm moving might trigger updates (in the case of setPos). This is a nice way, because I can be sure I have everything and it's iterative / without signals/slots. For the child added / removed it's the same principal.

      https://github.com/enjoysmath
      https://math.stackexchange.com/users/26327/exercisingmathematician

      1 Reply Last reply
      0
      • enjoysmathE enjoysmath has marked this topic as solved on

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved