Change view on current layout

Hi there.

So I have a new project that I can't seem to find information on in the docs. I want a way to automatically generate changes in the current view, adding rulers, changing layers that are visible, etc. using python code.

Let's say that someone is looking at a layout like this...

And you want to use the code to now see this...

Now let's say you want to add a ruler...

Or maybe change the layers that are visible

I am curious if there is a way to set all of these properties by utilizing the desired coordinates for this information. In regard to zooming in and out, I would simply like to force the user view based on the coordinate pairs that correspond the the corners of the new view.

I thought that I could access the LayoutView property, but I did not see anything within the API that would help me.

Any help is GREATLY appreciated.

Comments

  • @ManzAutomations There are tons of functions to achieve this and they are not hard to find:

    Some of them:

    Matthias

  • edited July 2023

    Hi ManzAutomations

    since you are trying to implement alot of customization into each view (zoom, layer visibility and annotations), I recommend to use "session" to save each view status.

    mw = pya.Application.instance().main_window()
    mw.save_session(sessionPath)
    mw.restore_session(sessionPath)
    

    here's a short video of how this session bookmark works.
    https://i.imgur.com/5eINkN7.mp4

    drag and drop *.lys into widget to load saved sessions


    class SessionWidget(pya.QWidget): def __init__(self, parent = None): super(SessionWidget, self).__init__() self.sessionListWidget = SessionListWidget() self.addSessionPB = pya.QPushButton("add") self.grid = pya.QGridLayout() self.grid.addWidget(self.sessionListWidget, 0, 0, 5, 5) self.grid.addWidget(self.addSessionPB, 5, 2, 1, 1) self.addSessionPB.clicked(lambda : self.sessionListWidget.addNewSessionListItem()) self.setLayout(self.grid) class SessionItemWidget(pya.QWidget): def __init__(self, mw, sessionPath, parent = None): super(SessionItemWidget, self).__init__() self.mw = mw self.sessionPath = sessionPath self.label = pya.QLabel(sessionPath) self.layout = pya.QVBoxLayout() self.layout.addWidget(self.label) self.setLayout(self.layout) def loadSession(self): self.mw.restore_session(self.sessionPath) class SessionListWidget(pya.QListWidget): def __init__(self, parent = None): super(SessionListWidget, self).__init__() self.container = [] self.mw = pya.Application.instance().main_window() self.cv = pya.CellView().active() self.itemClicked(lambda item : self.itemWidget(item).loadSession()) self.setAcceptDrops(True) self.setDragDropMode(pya.QAbstractItemView.DragDrop) def addNewSessionListItem(self): sessionFolder = "\\".join(pya.CellView().active().filename().split("\\")[0:-1]) sessionPath = "%s\\%s.lys" % (sessionFolder, self.count) self.addSessionListItem(sessionPath) self.mw.save_session(sessionPath) def addSessionListItem(self, sessionPath): item_widget = SessionItemWidget(self.mw, sessionPath) list_item_widget = pya.QListWidgetItem() list_item_widget.setSizeHint(item_widget.sizeHint()) self.container.append(item_widget) self.addItem(list_item_widget) self.setItemWidget(list_item_widget, item_widget) def dragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def dragMoveEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(pya.Qt.CopyAction) event.accept() else: event.ignore() def dropEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(pya.Qt.CopyAction) event.accept() links = [str(url.toLocalFile()) for url in event.mimeData().urls() if str(url.toLocalFile())[-3::] == "lys" ] for sessionPath in links: self.addSessionListItem(sessionPath) else: event.ignore() s = SessionWidget() s.show()
  • edited July 2023

    @Matthias Thank you so much for your answer. I am still new to the API, so this is a huge help.

    @RawrRanger, this idea may not be helpful in my case given that I am generating the exact locations dynamically and not by user input. However, the idea is wonderful and is definitely an interesting thought. Thank you so much!

  • Hi ManzAutomations

    here's an example of showing a cell and with custom zoom, layer and annotation

    import pya
    
    def customView(cellName, zoomBox = None, hideLayer=[], annotationsPoints = []):
        mainWindow    = pya.Application.instance().main_window()
        layoutView    = mainWindow.current_view()                #https://www.klayout.de/doc-qt5/code/class_LayoutView.html
        cellView      = layoutView.active_cellview()             #https://www.klayout.de/doc-qt5/code/class_CellView.html
        layout        = cellView.layout()                        #https://www.klayout.de/doc-qt5/code/class_Layout.html
        cellView.cell = layout.cell(cellName)                    #show cell as new top
    
        layoutView.show_all_cells()                            
        layoutView.clear_annotations()
    
        if zoomBox:                                              #zoom to fit given box, or fit all shapes
            layoutView.zoom_box(pya.DBox(*zoomBox))
        else:
            layoutView.zoom_fit()
    
        for layerProperties in layoutView.each_layer():          #loop through all layer and hide it if layer Num match 
            layerProperties.visible = not((layerProperties.source_layer, layerProperties.source_datatype) in hideLayer)
    
        for points in annotationsPoints:                         # add Ruler at given points
            annotation    = pya.Annotation()
            annotation.p1 = pya.DPoint(*points[0:2])
            annotation.p2 = pya.DPoint(*points[2:4])
            layoutView. insert_annotation(annotation)
    

    function can be use like this.
    show Cell "A" as new top and zoom to given box (-1.5, -1.5, 2.5, 2.5),
    show all layers but hide layer 2/0 and 4/0 if those two layer exist
    add two annotation at given coordinate (0, 0, 1, 1) and (-1, 1, 0, 0)

    customView(
        cellName          = "A", 
        zoomBox           = (-1.5, -1.5, 2.5, 2.5), 
        hideLayer         = [(2,0), (4,0)],
        annotationsPoints = [(0, 0, 1, 1),(-1, 1, 0, 0)]
    )
    
  • @RawrRanger That is exactly what I needed! Thank you so much!

Sign In or Register to comment.