tkinterのGUIデザイナーPAGEを使ってみる
pythonを使ってGUIソフトを作りたいと思う機会は多いのですが、気軽に作ることができないのが難点です。
pythonをインストールすることでデフォルトで入っていることが多いのでライブラリはtkinterを使おうと思うのですが、
画面のモジュール配置やレイアウトをコードで書いていくのは中々辛いです。。。
そこでPAGEというソフトを使ってVisual StudioのようにGUIでマウスを使ってウィンドウのレイアウトを作っていきます。
インストール
PAGEのインストールは下記サイトからできます。
起動
python page.py
GUI画面の編集
PAGEで画面の編集を行います。
今回はサンプルとして、ボタンを押したら画面上の数字が増えるようなソフトを作成します。
- LabelとButtonを画面に追加します
- Aliasに各種モジュールの名前を入力します
- 名前を入力した後、画像と同じ名前になっていることを確認します
画面に追加したLabelを中クリックしてWidget -> Set Textを選択します。
サンプルでは数字を増やしていきたいので初めは0にしておきます。
次にButtonも同じようにWidget -> Set Textを選択し、"Increment"とします。
次にButtonを押された時のイベント関数を追加します。
Buttonを中クリックしてWidget -> Set Commandを選択し"IncrementButtonOnClick"とします。
これで画面の変更は終了です。
変更したプロジェクトをFile -> Save asで保存します。
名前はpage_testとします。
GUIコード生成
これまで作成した画面をpythonファイルに出力します。
2種類生成することになりますが、まずは画面の設定等が記載されているファイルを生成します。
Gen_Python -> Generate python GUIを選択します。
ウィンドウが出てきますのでSaveを選択します。
次はコールバック関数等が記載されているサポートファイルを生成します。
Gen_Python -> Generate Support Moduleを選択し、こちらもSaveを選択します。
GUIコードの確認
ここでpythonファイルを確認してみましょう。
画面のレイアウト等の情報はpage_test.pyに記載されていますが、ボタンを押した時のイベント関数はpage_test_support.pyに記載されています。
ここで他のサイトを見てみると処理を変更したい場合はpage_test_support.pyを直接変更しているようです。
しかし、これまでの操作でもわかるようにこれらのコードはPAGEによって生成されているものです。
レイアウトを変更する度に生成し直す必要があるので、手作業で変更を加えてもツールによって上書きされてしまう可能性があります。
(実際に使ってみた感じでは、再生成するときに手作業の部分だけ変更を残してくれる時もあったのですが、時々きちんと残せない場合もあるようです。)
そこで、できるだけ生成されたファイルに変更を加えないようにしてソフトを作っていきます。
page_test.py
import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import os.path
_script = sys.argv[0]
_location = os.path.dirname(_script)
import page_test_support
_bgcolor = '#d9d9d9' # X11 color: 'gray85'
_fgcolor = '#000000' # X11 color: 'black'
_compcolor = 'gray40' # X11 color: #666666
_ana1color = '#c3c3c3' # Closest X11 color: 'gray76'
_ana2color = 'beige' # X11 color: #f5f5dc
_tabfg1 = 'black'
_tabfg2 = 'black'
_tabbg1 = 'grey75'
_tabbg2 = 'grey89'
_bgmode = 'light'
class Toplevel1:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
top.geometry("600x450+316+1096")
top.minsize(72, 15)
top.maxsize(3008, 1554)
top.resizable(1, 1)
top.title("Toplevel 0")
top.configure(background="#d9d9d9")
self.top = top
self.CountLabel = tk.Label(self.top)
self.CountLabel.place(relx=0.0, rely=0.0, height=22, width=39)
self.CountLabel.configure(anchor='w')
self.CountLabel.configure(background="#d9d9d9")
self.CountLabel.configure(compound='left')
self.CountLabel.configure(foreground="#000000")
self.CountLabel.configure(text='''0''')
self.IncrementButton = tk.Button(self.top)
self.IncrementButton.place(relx=0.0, rely=0.067, height=28, width=77)
self.IncrementButton.configure(activebackground="beige")
self.IncrementButton.configure(activeforeground="black")
self.IncrementButton.configure(background="#d9d9d9")
self.IncrementButton.configure(command=page_test_support.IncrementButtonOnClick)
self.IncrementButton.configure(compound='left')
self.IncrementButton.configure(foreground="#000000")
self.IncrementButton.configure(highlightbackground="#d9d9d9")
self.IncrementButton.configure(highlightcolor="black")
self.IncrementButton.configure(text='''Increment''')
def start_up():
page_test_support.main()
if __name__ == '__main__':
page_test_support.main()
page_test_support.py
import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import page_test
def main(*args):
'''Main entry point for the application.'''
global root
root = tk.Tk()
root.protocol( 'WM_DELETE_WINDOW' , root.destroy)
# Creates a toplevel widget.
global _top1, _w1
_top1 = root
_w1 = page_test.Toplevel1(_top1)
root.mainloop()
def IncrementButtonOnClick(*args):
print('page_test_support.IncrementButtonOnClick')
for arg in args:
print (' another arg:', arg)
sys.stdout.flush()
if __name__ == '__main__':
page_test.start_up()
GUIコードの編集
GUIコード
page_test.pyの変更はありません。
GUIサポートコード
page_test_support.pyは下記のadd部分を追加します。
これから新規追加するpage_test_modを呼び出します。
page_test_support.py
from operator import mod
import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import page_test
import page_test_mod
def main(*args):
'''Main entry point for the application.'''
global root
root = tk.Tk()
root.protocol( 'WM_DELETE_WINDOW' , root.destroy)
# Creates a toplevel widget.
global _top1, _w2
_top1 = root
_w1 = page_test.Toplevel1(_top1)
#add
global mod
mod = page_test_mod.page_test_mod(_w1)
root.mainloop()
def IncrementButtonOnClick(*args):
print('page_test_support.IncrementButtonOnClick')
for arg in args:
print (' another arg:', arg)
sys.stdout.flush()
#add
mod.IncrementButtonOnClick()
if __name__ == '__main__':
page_test.start_up()
新規追加コード
最後に新規追加でpage_test_mod.pyを作成します。
イベント関数の実行処理はこのファイルに記載します。
page_test_mod.py
#! /usr/bin/env python
class page_test_mod:
def __init__(self, w):
self.w = w
pass
def IncrementButtonOnClick(self):
s = self.w.CountLabel["text"]
i = int(s) + 1
self.w.CountLabel["text"] = str(i)
if __name__ == '__main__':
pass
Discussion
有用な記事、ありがとうございます。
Pageのリンクが404の模様です。多分こちらが新しいURLかと
shin1007さん
コメント有難うございます。
URL更新しました。
この記事がお役に立ったようで嬉しいです!