PyLAFでのラボアプリの作成

コンポーネントの作成

PyLAFアプリケーションの最小単位です。 コンポーネントはロジックとGUIを搭載しています。 単一のコンポーネントに目的の異なる複数のGUIを搭載することができます。 実行時は、App(Frame,Equipment)フレームまたはEmbed(LabelFrame,Equipment)フレーム配下に 本体と、それに関連づけられたGUIが配置して活用します。

テストセット(エンベッド型、トップレベル型)

PyLAFではコンポーネントを連携させるスクリプトを記述できます。 複数のコンポーネントを同一のフレームに格納するエンベッド型、コンポーネントを各々独自のトップレベルウィンドウで表示するトップレベル型の2種類を想定しています。 エンベッド型はTkinter.LabelFrameを継承し、フレームタイトルを右クリックするとアプリケーションのポップアップメニューが開きます。 トップレベル型はTkinter.Frameを継承し、Toplevelウィンドウの配下に置かれることを想定しています。ウィンドウにアプリケーションのメニューバーがつきます。 テストセットは主にコンポーネントの構成を簡単に変更したい場合に使用します。

複合コンポーネント(エンベッド型、ポップアップ型)

PyLAFでは連携させたサブコンポーネントで複合コンポーネントを作ることができます。 複合コンポーネントはテストセットを再利用したい場合に使用します。 複合コンポーネントも一般のコンポーネントと同様にテストセットや、他の複合コンポーネントの部品となることができます。

プログラム例

典型的なコンポーネントの例

EasyComponentクラスを使うと単一プロッタと単純なパラメータエントリからなる典型的なコンポーネントを作成できます。 作成したコンポーネントをApp(Frame,Equipment)フレームで包むとほかのTkウィジェットと同様に扱うことができます。

# coding: utf-8
import Tkinter
# PyLAFをロードするとTkinterが暗黙でインポートされるが、
# Pythonに不慣れなユーザが混乱しないよう、わかりやすさの為にTkinterを明示的にインポートした
from PyLAF import *
from scipy import savetxt

class FGSIN(EasyComponent):
    PLOTTER = Oscilloscope
    def __init__(self,master=None):
        EasyComponent.__init__(self,master)
        self.mag   = EasyPort(Variable(1.),'Magnitude [mV]').bind(self.trigger)
        self.freq  = EasyPort(Variable(0.01),'Frequency [MHz]').bind(self.trigger)
        self.phase = EasyPort(Variable(0.),'Phase Offset [deg]').bind(self.trigger)
        self.bias  = EasyPort(Variable(0.),'Bias Voltage [mV]').bind(self.trigger)
        self.dt    = EasyPort(Variable(1.),'Time Step [us]').bind(self.trigger)
        self.tend  = EasyPort(Variable(500.),'End [us]').bind(self.trigger)
        self._menu = [['File', ['Load', None],
                               ['Save', ['All', None],
                                        ['As' , self.save]]],
                       ['Edit', ['Copy' , None],
                                ['Cut'  , None],
                                ['Paste', None]]
                      ]
    def trigger(self):
        t = arange(0.,self.tend.get(),self.dt.get())
        self.sig_out.set(self.mag.get() * sin(2 * pi * self.freq.get() * t + self.phase.get() / 180. * pi) + self.bias.get())
    def save(self):
        fname = tkFileDialog.asksaveasfilename(title='Save As?')
        if fname != "":
            file = open(fname,'w')
            savetxt(file,self.sig_out.get().transpose(),delimiter=',')
            file.close()

if __name__ == '__main__':
    o = App(Tkinter.Tk(),FGSIN)       # ルートウインドウ配下にEquipment.Appフレームを、その下にFGSINコンポーネント本体とGUIとを配置する。
    o.master.title('FGSIN'); o.pack() # ルートウィンドウのタイトル設定と、Equipment.Appフレームのパック。
    o.component.trigger()             # 初期値でグラフ表示させるためのトリガー
    Tkinter.mainloop()