CellView.on_technology_changed is not emitted

Hi @Matthias,

I was trying to use this new signal for CellView class "on_technology_changed" and it seems doesn't work properly.
Here is the test code I was using:

class MainWindow(pya.QMainWindow):
    def __init__(self, parent=None):
        w = pya.QWidget(self)
        layout = pya.QVBoxLayout(w)

        button = pya.QPushButton("Check technology", self)
        button.clicked(self._check_technology_from_button)
        layout.addWidget(button)

        self.tech_label_btn = pya.QLabel(f"Technology from button click:", self)
        layout.addWidget(self.tech_label_btn)
        self.tech_label_clv = pya.QLabel(f"Technology from CellView signal:", self)
        layout.addWidget(self.tech_label_clv)

        # connect to signal from CellView
        pya.CellView.active().on_technology_changed(self._check_technology_from_signal)

        self.setCentralWidget(w)

    def _check_technology_from_signal(self):
        self.tech_label_clv.text = f"Technology from CellView signal: {pya.CellView.active().technology}"

    def _check_technology_from_button(self):
        self.tech_label_btn.text = f"Technology from button click: {pya.CellView.active().technology}"


if __name__=="__main__":
    wnd = MainWindow()
    wnd.show()        

Signal from button works fine and shows updated technology name every time but CellView does not.

Comments

  • Finally a working full sample :)

    Thanks for the code and reporting the problem. I can reproduce the issue. The event is working with Ruby, but not with Python. Maybe a object reference count issue. I need to debug that problem.

    I have created a ticket for this: https://github.com/KLayout/klayout/issues/1043

    Matthias

  • It seems to be a reference counting issue.

    I found a quick workaround: if you keep a reference to the Signal object, the event is triggered:

            # connect to signal from CellView
            self._event = pya.CellView.active().on_technology_changed
            self._event.add(self._check_technology_from_signal)
    

    Matthias

  • Here is another workaround and it's even kind of cleaner:

    class MainWindow(pya.QMainWindow):
        def __init__(self, parent=None):
            w = pya.QWidget(self)
            layout = pya.QVBoxLayout(w)
            self._cellview = pya.CellView.active()
    
            button = pya.QPushButton("Check technology", self)
            button.clicked(self._check_technology_from_button)
            layout.addWidget(button)
    
            self.tech_label_btn = pya.QLabel(f"Technology from button click:", self)
            layout.addWidget(self.tech_label_btn)
            self.tech_label_clv = pya.QLabel(f"Technology from CellView signal:", self)
            layout.addWidget(self.tech_label_clv)
    
            # connect to signal from CellView
            self._cellview.on_technology_changed.add(self._check_technology_from_signal)
    
            self.setCentralWidget(w)
    
        def _check_technology_from_signal(self):
            self.tech_label_clv.text = f"Technology from CellView signal: {self._cellview.technology}"
    
        def _check_technology_from_button(self):
            self.tech_label_btn.text = f"Technology from button click: {self._cellview.technology}"
    
    
    if __name__=="__main__":
        wnd = MainWindow()
        wnd.show()        
    

    This solution is keeping the Cellview the signal was attached to. The active Cellview may change and hence it's a good idea to keep the reference rather than attaching the signal to one and reporting the technology from another Cellview.

    The root cause of the issue is the lifetime of the CellView object. Actually this is not the internal object, but a temporary Python proxy. So when you attach the signal to the temporary proxy returned by "pya.CellView::active()", it gets disconnected as soon as this proxy goes out of scope. By keeping a reference to the proxy, the signal remains attached.

    For the button it works as the button object is held as a reference inside the widget tree.

    I admit that is not intuitive, but that is a consequence of the C++ centric architecture. I'll see if I can make this more intuitive, but so far I think this is an acceptable workaround.

    Matthias

  • thank you, @Matthias, this works and totally fine for me!

Sign In or Register to comment.