LayoutView.on_annotations_changed behavior

Hi, Matthias!

Looks like LayoutView.on_annotations_changed() is called when LayoutView.each_annotation() is not updated with last change (added or removed annotation), so as of now it's not possible to track exact annotations changes.

Other problem is QObject.sender(): I expect it to return current view, but None is returned.

I tried next script in 0.26.4 and 0.27.9:

import pya

instance = None

class Test(pya.QObject):

    def __init__(self, current_view):
        self.__current_view = current_view
        self.__current_view.on_annotations_changed = self.annotations_changed

    def annotations_changed(self):
        print('sender ', self.sender())
        for annotation in self.__current_view.each_annotation():
            print(annotation)

def test():
    global instance
    instance = Test(pya.Application.instance().main_window().current_view())

Comments

  • Same problem with Annotation.is_valid() that still refer to out-of-date state of annotations.

  • Hi Eugene,

    "annotations_changed" is not a Qt signal, that's why "sender()" does not work. But you can add your own arguments using this scheme:

    ...
            self.__current_view.on_annotations_changed = lambda: self.annotations_changed(self.__current_view)
    ...
        def annotations_changed(self, view):
            print('sender ', view)
    ...
    

    You're right that the event is sent too early. I have not debugged the problem yet, but I can say that the event it sent only on the first change and from somewhere deep inside the code, so I assume the annotation list has not been finalized yet.

    The purpose of the event is to do something very simple like setting a flag and evaluate it later. If you're on Qt, a good strategy for "later" is to use a QTimer, set it to zero timeout and single shot. In this case then timer will fire after everything is done and the program returns to the UI main loop. Here is code which uses this scheme:

    import pya
    
    instance = None
    
    class Test(pya.QObject):
    
        def __init__(self, current_view):
            self.__timer = pya.QTimer(self)
            self.__timer.setInterval(0)
            self.__timer.setSingleShot(True)
            self.__current_view = current_view
            self.__current_view.on_annotations_changed = self.annotations_changed_event
            self.__timer.timeout = lambda: self.annotations_changed(self.__current_view)
    
        def annotations_changed_event(self):
            self.__timer.start()
    
        def annotations_changed(self, view):
            print('sender ', view)
            for annotation in self.__current_view.each_annotation():
                print(annotation)
    
    def test():
        global instance
        instance = Test(pya.Application.instance().main_window().current_view())
    

    Matthias

  • Hi, Matthias!

    Thank you for explanations and workaround!

Sign In or Register to comment.