mirror of https://github.com/KLayout/klayout.git
265 lines
12 KiB
XML
265 lines
12 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
|
|
|
<doc>
|
|
|
|
<title>Introduction</title>
|
|
<keyword name="Programming"/>
|
|
<keyword name="RBA"/>
|
|
<keyword name="Ruby scripts"/>
|
|
<keyword name="Python"/>
|
|
<keyword name="pya"/>
|
|
<keyword name="Python scripts"/>
|
|
|
|
<p>
|
|
This chapter is about programming extensions for KLayout using the integrated Ruby API (RBA) or Python API (pya).
|
|
</p>
|
|
|
|
<p>
|
|
To use RBA scripts, KLayout must be compiled with the Ruby interpreter. Check under "Help/About" whether
|
|
support is available. If there is, the "Build options" will include a "Ruby" or "Python" interpreter or both.
|
|
RBA scripts require a Ruby interpreter. To use pya scripts, Python support must be included.
|
|
</p>
|
|
|
|
<p>
|
|
KLayout comes with the Qt library included into the Ruby or Python API. This means, KLayout scripts
|
|
can access the full Qt API if Qt binding is available. Check whether "Qt bindings for scripts" is included
|
|
in the build options on the "Help/About" page.
|
|
</p>
|
|
|
|
<p>
|
|
Basically there are scripts and macros:
|
|
</p>
|
|
|
|
<ul>
|
|
<li>
|
|
<b>Scripts</b> are simple text files which are prepared externally and KLayout acts as an interpreter for these scripts.
|
|
A special case of scripts is included code, while is loaded into other scripts or macros using "require" on Ruby
|
|
or "import" on Python. Scripts have been the only way to code Ruby functionality in version 0.21 and earlier.
|
|
</li>
|
|
<li>
|
|
<b>Macros</b> are special XML files which contain Ruby code plus some additional information required to
|
|
link them into the system, i.e. automatically execute them on startup or provide menu entries for them.
|
|
They can load normal ".rb" or ".py" files to implement libraries of classes in the usual way. Macros are managed and developed conveniently
|
|
in the integrated macro development environment along with the supporting files. This method is the preferred way of creating application
|
|
extensions and is described in this chapter.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
Before you start, please make yourself familiar with the macro development integrated environment (<link href="/about/macro_editor.xml"/>).
|
|
This documentation also assumes that you familiar with the Ruby programming language. There are numerous
|
|
books and tutorials about Ruby. The most famous one is the "pickaxe book" (Programming Ruby - The Pragmatic Programmers Guide) by Dave Thomas.
|
|
If you are familiar with Ruby there is a technical article about the way Ruby and KLayout's core are
|
|
integrated (<link href="/programming/ruby_binding.xml"/>). There are special articles about the integrated Qt binding
|
|
(<link href="/programming/qt_binding.xml"/>) and PCell programming (<link href="/programming/ruby_pcells.xml"/>). If you want to
|
|
use Python, please read the python implementation article (<link href="/programming/python.xml"/>) for details about how to
|
|
translate Ruby samples into Python and specific details of the Python integration.
|
|
</p>
|
|
|
|
<p>
|
|
An introduction into the basic concepts of the KLayout API are given in the article about the
|
|
application API (<link href="/programming/application_api.xml"/>) and about the database API (<link href="/programming/database_api.xml"/>).
|
|
</p>
|
|
|
|
<h2>A First Sample</h2>
|
|
|
|
<p>
|
|
The first sample is already a complete macro which counts all selected paths, boxes, polygons or text objects.
|
|
It demonstrates how to set up a macro, how to deal with the selection and how to access the layout database.
|
|
</p>
|
|
|
|
<p>
|
|
Here is the code:
|
|
</p>
|
|
|
|
<pre>module MyMacro
|
|
|
|
include RBA
|
|
|
|
app = Application.instance
|
|
mw = app.main_window
|
|
|
|
lv = mw.current_view
|
|
if lv == nil
|
|
raise "Shape Statistics: No view selected"
|
|
end
|
|
|
|
paths = 0
|
|
polygons = 0
|
|
boxes = 0
|
|
texts = 0
|
|
|
|
lv.each_object_selected do |sel|
|
|
|
|
shape = sel.shape
|
|
|
|
if shape.is_path?
|
|
paths += 1
|
|
elsif shape.is_box?
|
|
boxes += 1
|
|
elsif shape.is_polygon?
|
|
polygons += 1
|
|
elsif shape.is_text?
|
|
texts += 1
|
|
end
|
|
|
|
end
|
|
|
|
s = "Paths: #{paths}\n"
|
|
s += "Polygons: #{polygons}\n"
|
|
s += "Boxes: #{boxes}\n"
|
|
s += "Texts: #{texts}\n"
|
|
|
|
MessageBox::info("Shape Statistics", s, MessageBox::Ok)
|
|
|
|
end</pre>
|
|
|
|
<p>
|
|
To run the macro, create a new macro in the macro development IDE: choose "Macros/Macro Development". Create a new macro
|
|
using the "+" button. Rename the macro to a suitable name. Copy the code above into the text. Load a layout, select some
|
|
objects and in the macro development IDE press F5. A message box will appear the tells us how may boxes, polygons etc.
|
|
we have selected.
|
|
</p>
|
|
|
|
<p>
|
|
If we look at the code, the first observation is that we put the whole script into our own namespace (we can use any name which is not used
|
|
otherwise). The advantage of that approach is that we can import the "RBA" namespace which makes life somewhat easier.
|
|
The RBA namespace contains all KLayout classes and constants.
|
|
If we would import the RBA namespace into the main namespace we would do that for all other scripts in KLayout since
|
|
the main namespace is a common resource for all scripts.
|
|
</p>
|
|
|
|
<p>
|
|
The first thing we do inside the macro is to access the layout view:
|
|
</p>
|
|
|
|
<pre> app = Application.instance
|
|
mw = app.main_window
|
|
|
|
lv = mw.current_view
|
|
if lv == nil
|
|
raise "Shape Statistics: No view selected"
|
|
end</pre>
|
|
|
|
<p>
|
|
The Application class (<class_doc href="Application"/>) is a representative for the KLayout application. Since there is only one application, it is a singleton.
|
|
We can obtain the singleton instance with the class method ("static" in the language of C++) "instance". It delivers a
|
|
reference to the only Application object which is the main entrance to all internals of KLayout.
|
|
</p>
|
|
|
|
<p>
|
|
The next object which is important is the MainWindow object (<class_doc href="MainWindow"/>). Currently there is only
|
|
one MainWindow object which can be obtained with the "main_window" method of the Application object. The MainWindow
|
|
object represents the application's window and manages the top level visual objects of the application.
|
|
The main visual components of the main window are the menus, the tool panels (cell tree, layer list, tool box, navigator ...)
|
|
and the layout views.
|
|
</p>
|
|
|
|
<p>
|
|
The layout view is the representation of a layout tab (<class_doc href="LayoutView"/>). That is basically the window to
|
|
the layouts loaded into that tab.
|
|
All related information such as the display settings, the zoom area, the layer properties and the informations about the
|
|
cell shown, the hierarchy levels and further settings go here.
|
|
</p>
|
|
|
|
<p>
|
|
A main window can display multiple tabs. Hence there are multiple LayoutView objects available. The currently selected
|
|
tab can be addressed with the "current_view" method. This method delivers the LayoutView object associated with that tab.
|
|
If no layout is loaded, that method returns nil (the Ruby for "nothing")
|
|
</p>
|
|
|
|
<p>
|
|
Actually the preparation step can be simplified without needing the Application and MainWindow object. For demonstration
|
|
purposes it was included however. Here is the short version:
|
|
</p>
|
|
|
|
<pre> lv = LayoutView.current || raise "Shape Statistics: No view selected"</pre>
|
|
|
|
<p>
|
|
The actual layouts loaded are entities separated from the views. Technically, there is a many-to-many relationship between layout views
|
|
and layout objects. A layout view may display multiple layouts and one layout may be displayed in multiple layout views.
|
|
In addition, a layout view can address different cells from a layout. A layout view has a current cell and a path
|
|
that leads to that cell. The path consists of a specific and unspecific part. The unspecific part of the path tells
|
|
where the cell we show as the current cell is located in the cell tree. The unspecific part is a tribute to the fact that
|
|
a cell can appear in different branches of the cell tree (i.e. as child of cell A and cell B). The specific part of the
|
|
path addresses a specific instance of within some cell (the "context cell") above in the hierarchy. A specific path is created when
|
|
we descend down in the hierarchy along a certain instantiation path.
|
|
</p>
|
|
|
|
<p>
|
|
Layout, current cell, context cell, specific and unspecific
|
|
path are combined into the CellView object (<class_doc href="CellView"/>). A layout view can have multiple cell views
|
|
corresponding to the different layouts that can be loaded into a panel. The cell views do not necessarily have to point
|
|
to different layouts.
|
|
</p>
|
|
|
|
<p>
|
|
For our sample we don't need the CellView objects, because we get all information directly from the view. But the
|
|
concept of that object is important to understand the API documentation.
|
|
Here we ask the layout view for all selected objects and collect the object counts:
|
|
</p>
|
|
|
|
<pre> lv.each_object_selected do |sel|
|
|
|
|
shape = sel.shape
|
|
|
|
if shape.is_path?
|
|
paths += 1
|
|
elsif shape.is_box?
|
|
boxes += 1
|
|
elsif shape.is_polygon?
|
|
polygons += 1
|
|
elsif shape.is_text?
|
|
texts += 1
|
|
end
|
|
|
|
end</pre>
|
|
|
|
<p>
|
|
"each_object_selected" is a method of the LayoutView object. More precisely it's an iterator which calls the
|
|
given block for each selected object. Since the layout view can show multiple layouts, the selected objects may
|
|
originate from different layouts. In addition, the object may be selected in a child cell of the current cell.
|
|
Hence, the selection is described by a cell view index (indicating which layout it resided in), an instantiation path (a sequence of instances leading to
|
|
the cell containing the selected object from the current cell) and the actual object selected.
|
|
That information is combined into an ObjectInstPath object (<class_doc href="ObjectInstPath"/>).
|
|
</p>
|
|
|
|
<p>
|
|
In our case we are not interested in the cell view that shape lives in. Neither are we in the instantiation path.
|
|
Hence all we need is the shape and we can obtain it with the "shape" method.
|
|
This method delivers a Shape object (<class_doc href="Shape"/>), which is some kind of pointer (a "proxy") to the
|
|
actual shape. The actual shape is either a polygon, a box, a text or a path. The Shape object has multiple
|
|
identities and we can ask it what shape type is represents. For that, the Shape object offers methods like "is_box?" etc.
|
|
If we know the type we can ask it for the actual object and fetch a Polygon (<class_doc href="Polygon"/>), a
|
|
Box (<class_doc href="Box"/>), a Text (<class_doc href="Text"/>) or a Path object (<class_doc href="Path"/>).
|
|
For our sample however we don't need access to the actual object.
|
|
</p>
|
|
|
|
<p>
|
|
Finally we put together a message and display it in a message box:
|
|
</p>
|
|
|
|
<pre> s = "Paths: #{paths}\n"
|
|
s += "Polygons: #{polygons}\n"
|
|
s += "Boxes: #{boxes}\n"
|
|
s += "Texts: #{texts}\n"
|
|
|
|
MessageBox::info("Shape Statistics", s, MessageBox::Ok)</pre>
|
|
|
|
<p>
|
|
MessageBox (<class_doc href="MessageBox"/>) is a class that provides modal message dialogs through
|
|
several class methods. "info" shows an information box and with the given title and message. The third
|
|
parameter indicates which buttons will be shown. In that case, one "Ok" button is sufficient because
|
|
we don't want to take specific actions when the message box is closed. MessageBox is not the Qt class,
|
|
which is also available (QMessageBox), but less portable in case a user does not have Qt binding enabled.
|
|
</p>
|
|
|
|
<p>
|
|
This is just a simple example, but it already illustrates some basic concepts.
|
|
For a in-depth introduction into the API, read <link href="/programming/application_api.xml"/> and <link href="/programming/database_api.xml"/>.
|
|
</p>
|
|
|
|
</doc>
|
|
|