先日は、
■ ラベルとボタンとテキストボックスの表示をする:tkinter【 Python 3.10 】
にて、GUIによる処理について書きました。Pythonではtkを使ったプログラミングが可能なので、tkinterを使うとウィジェットを使った処理を作る事ができます。ひな形としては、
のような物になりますが、mainloop()の部分がウインドウを表示し続ける為のループになります。このコードを実行すると、
のようにウインドウを表示して実行できるようになります。
そして、ウィジェットを配置する場合には、packをしなければならないので
のようにラベルを表示した場合には、その後に、pack()を記述して表示を行います。実行すると、
のようにラベルを表示する事ができます。ウィジェットの配置の場合、前述のように
■ 指定
■ 表示
の記述を一つのまとまりとして、個別のウィジェットに対して行う事になります。
コンソールアプリの 【 input() 】 関数の処理をする場合には、
■ テキストボックス : 文字列の入力
■ ボ タ ン : 処理
を行うのですが、テキストボックスの表示ですが、
のようなコードを書くと、
のように文字の入力が可能なテキストボックスを表示できるようになりますが、表示する内容を変更できるので、
のようなコードを書くと、
のようにテキストボックスの中に文字を入力したり、何もないように消去することもできます。
ボタンについては、
のような表記になりますが、ボタンはpack()の記述が必要ありません。
これはボタンを表示するだけなので、実際に実行すると、
のようにクリックが可能な物を配置しただけの状態になります。
ボタンの制御は、 【 関数の実行 】 で行えるようになっているので、
のように実行する関数を用意して、ボタンのオプションで関数の呼び出しをするような流れになります。その為、ボタンに処理を実装する場合には、
のように関数とボタンの記述を1セットで扱う事になります。コードを実行すると、
のような表示になり、上のテキストボックスに
のように文字列を入力して実行すると、
のように取得した文字列を表示する事ができます。先日のコードですが、
■ ラベルの表示 : print()関数相当
■ ボタンでの制御 : input()関数相当
なので、コンソールアプリで上記の関数を実行して処理をする際の内容をGUI環境で行う場合の記述の基本部分になりますが、変数を取得して、それを表示するだけでも、ウィジェットを使う場合には、
【 ウィジェットの表示 】 + 【 処理 】
と言う形になるので、行数が肥大化する傾向があります。
先日は、こんな感じでtkinterのウィジェットの使い方と、プログラミング言語を使う上での、
■ GUI上で表示
■ GUI上で入力した物を表示する
と言う 【 コンソールアプリで最初に登場するような内容 】 を扱ったのですが、今回もGUIでの処理について書こうかなと思います。
G UI環境 : TkinterのTk()とttk()
先日は、TkinterでTk()を使ってウィジェットを使いましたが、Tkinterのプログラムを見ると、
【 from tkinter import ttk 】
と言う読み込みが登場する事があります。
これは、デザインの異なるUIを表示する時に使用しますが、
■ Tk() : 立体的
■ ttk() : 平面的
な表示になります。その為、凹凸の主張がないUIを表示して使用したい場合には、ttkを使う事になりますが、当然、Tk()とは異なる記述になります。
■ ttk()
tkinter.ttkは、 【 tk 8.5 】 から導入された物で、モダンなデザインのUIの表示や機能を増やした物になります。ttkでは、ttkにシナ海ウィジェットも存在しており、
■ ttkにあってtkにない物
■ Combobox
■ Notebook
■ Progressbar
■ Separator
■ Sizegrip
■ Treeview
などが使用できます。逆にtkにあってttkにない物も存在しますから、目的で使い分けることになります。
記述についても異なるのですが、ttkについては、次の機会に書こうかなと思います。
Tkinterを使う場合、現在のバージョンでは、TK()とttk()が使用できるので、
【 from tkinter import Tk 】
【 from tkinter import ttk 】
の2つの記述が刺されている物がありますが、これを行うと両方の記述を使う事が出来ます。コードを書く場合に、tkinterの中からウィジェットを呼び出す場合に、個別に呼び出すと記述が長くなる場合がありますが、多用する場合だと、 【 as 】 を使う事で短縮した記述で使用できるように変更できます。例えば、
【 from tkinter import messegebox as mb 】
のようにすると、messagebox()の記述をmb()で行えるようになります。
LabelやEntryが多い場合だと、ループで作ってその番号を変数として使うという方法もありますが、呼び出す関数の記述が長い場合にはasを使って短縮してコード内で使う事もできます。
ウ ィジェットを使う : massagebox
JavaScriptでは、コンソールが存在しないので、Hello,World!を簡単に表示したい場合だと、メソッドを使って表示をする仕組みになっていますが、この時に使用するのがalert()メソッドになります。JavaScriptでは、関数もメソッド扱いになっていますが、Pythonだとメソッドはクラス内に記述した関数の事を指しています。どちらも関数ですが、使用する言語によって対象の呼び名が違う事があるので注意が必要です。
tkinterでもalert()と同じような事をmessageboxで行う事が出来ます。
■ messagebox
tkinter.messegebox()
で指定しますが、記述によって表記する物が変わって
きます。
実際にコードを書いてみると、
のように1行で表示できるのですが、
■ タイトル
■ 表示する内容
を指定する事ができます。実際に実行すると、
のようになり、ウインドウとメッセージボックスの2つがひょじされています。messageboxをインポートして使用するとこうした事が出来ますが、モジュールノインポート時には 【 as 】 を使う事で記述を短縮できるので、
のようにmbに置き換えると、メッセージボックスの呼び出しは、mb.仕様の指定で呼び出す事が出来るようになります。
■ メッセージボックスの種類
メッセージボックスは用途によって使い分けることが出来る仕様になっていますが、メッセージボックスの指定には、
のような物があります。メッセージボックスには二種類の指定があり、
■ show~ : 表示とOKのみの表示
■ ask~ : 表示とYES/NOの判定用のボタンがある
から選択できるようになっています。 【 show~ 】 の場合、
■ show~の形の物
のようになっており、
の三種類から選択する事になります。そして、 【 ask~ 】 の場合、
の4種類があり、
のように選択肢の項目の文字が変わる仕様になっています。これを閉じても、mainloopでtk自体は動いているので、
のようにウインドウの表示自体は維持されます。
■ ボタンと戻り値
ボタンによって戻り値が異なるのですが、
■ 戻り値が 【 OK 】 になるもの
■ showinfo
■ showerror
■ showwarning
■ 戻り値が 【 True/False 】 になるもの
■ askyesno
■ askokcancel
■ asktrycancel
■ 戻り値が 【 yes/no 】 になるもの
■ askquestion
のような違いがあります。
■ ボタンで表示する
これは先日の応用になりますが、ボタンをクリックして表示をする場合には、関数で記述をして、ボタンで呼び出せばいいので、
のようなコードを書くことになります。これを実行すると、
のようにウインドウが表示されて、
のウインドウ内のボタンをクリックすると、メッセージボックスが表示されます。
このように 【 ボタンで関数の実行 】 ができるので、フロントエンドの記述と変数の取得の方法がウィジェットの場合だと増えてしまうのですが、フロントエンドの処理がGUIになっただけなので、操作以外の内部処理を担うバックエンドでの処理部分はコンソールアプリと全く同じ考え方になります。その為、バックエンドでの処理を理解した上でフロントエンドの実装の仕方を考えるという流れになりますが、ボタンでの操作だと 【 関数による制御の実装 】 なので、コンソールアプリとほとんど同じです。今回の処理はボタンなので、JavaScriptのonclick()メソッドでボタンボクリックへの処理を追加したような感じになりますが、ウィジェットの動作に対してスクリプトを走らせる上で関数を使う点では考え方は同じです。この時に、今回のように表示だけをするような物を使ったり、前回のようにオブジェクトのデータ参照とテータの取得と表示などもできるので、関数で制御をすると色々な事が出来ます。
T kinterのコード
今回は、GUIの部品について書いていますが、構造的には
■ Tk()
┃
┗ ■ フレーム
┃
┗ ■ ウィジェット
となっているので、Tkの宣言をした後にそれを使う場合にはフレームを指定する事になります。そして、Tk()の宣言はベースになるので、コードを見てみると多くの事例でrootと言う変数名で宣言されていると思います。
あと、構造的に 【 クラス 】 で管理したほう使いやすいので、ウィジェットのコードをそのまま見た場合には、知識があ内状態で見た場合、何がどうなっているのか解らない物になっていますが、これは、
■ Classの構造
■ Tkinterの構造
と言う全く別の物を使っているので、一つのまとまりになっていても解りにくい構造になっているはずです。多分、Classの知識がない状態でコードを見ても全く分からないのですが、構造を理科敷いてそれぞれに必要な知識を身に着けてから確認するとコードの意味が理解できるようになります。
Classについては、標準ライブラリで学習できる物なので、コンソールアプリで挙動と使い方を覚えて使用する事になりますが、この構造を使って、GUIの表示をTkinterで行っているコードが、Classを使ったGUIの制御になります。なので、ウィジェットのプログラミングの場合に、コードの記述で、classで始まる記述の場合、
■ 基底クラス
■ 継承
■ インスタンスの生成
■ メソッド
の構造が包含されているはずですから、基礎的なクラスの概念と、GUIのプログラムの知識がないとコードの内容が理解できないので、コンソールアプリの学習における
■ 変数
■ 関数
■ クラス
の知識は必須になります。先日書いたように、処理をボタンで実行するような状態にする場合、 【 関数の宣言と実行 】 で処理を実装する事になりますから、 【 関数の理解 】 は必須となります。
P ythonの外部ライブラリ
GUIだと、PyGTKやPyQtなどがありますが、この2つは、GTKとQTと言う二種類のGUI環境になります。Linuxのウインドウマネージャーには、
■ Gnome
■ KDE
がありますが、
■ GTK : Gnome
■ QT : KDE
が使用されています。その為、この二者を見て比較するとどう言った物なのかの確認が出来ると思います。
ちなみに、GTKの正式名は、 【 Gimp Tool Kit 】 なので、GIMPを実装する時に使用されたGUI環境になります。ちなみに、GTK2以降だと、 【 手書き入力による日本語入力 】 など様々な日本語入力に対応しています。(im-ja)
ちなみに、MozillaのFirefoxやThunderbirdやInkscapeでもGTKが使用されています。QtはMakeHumanでも使用されているようで、Qtがないというエラーが出る場合がありますが、AvidemuxやfreecadやMuseDcoreで称されており、NukeやMayaもQtが使用されています。
A ppendex
先日は、GUI環境での、print()関数とinput()関数相当の事を行いましたが、HTMLのように最初からGUIの環境だと、データの取得をオブジェクトから行うような処理が必須となります。HTMLでは、JavaScriptなどを使う事になりますが、ESやTypeScriptで文字を書き換える場合だと、タグに対しての処理を実装する事になります。例えば、
■ DIVコンテナ
┃
┗ ■ Pタグ
のような構造を作ると、<DIV>と<P>のタグをエレメントとして使用できるようになります。JavaScriptで文字の切り替えをする場合、ボタンではなく、エレメントに対してonclick()イベントを実装できるので、この条件だと、
■ DIVコンテナ : クリックイベントの実装
■ Pタグ : 表示の対象
で処理を実装sることができます。この時に、
onclickイベント = function(){
処理;
};
のような形で記述できるので、
【 対象のエレメント 】 .メソッド
で実行するので、
■ クリックするイベント
【 対象のエレメント 】 .onclick
■ 表示の切り替え
【 対象のエレメント 】 .interHTML
になります。そして対象のエレメントですが、取得をするので、
getElementById()
で取得する事になりますが、この記述だと、
エレメント(タグやCSS)に指定したIDを取得する
だけなので、場所の指定をする必要があります。その為、対象の記述は、ページ内の階層で考えることになりますから、上記の構造だとそのまま使えるので、
document.getElementById()
で取得できます。と言う事は、
document.getElementById('DIVコンテナのID').onclick = 関数
で記述をして、クリックの判定をする事になります。このイベントにを指定した関数の実行を代入するので、Pタグの
document.getElementById('PタグのID')
に対して、InterHTMLを適応して記述の更新をするので、
document.getElementById('PタグのID').onclick = 表示内容
を記述する事になります。そうなると、この部分は、
document.getElementById('PタグのID').onclick = '文字列';
となるのですが、改行が必要なので、最後にセミコロンを入れます。
これは処理の無いようなので、これを関数に包含する必要がりますから、引数なしの関数のfunction()で囲むことになります。
JavaScriptでは、スコープがあるので、{}を使ってその間に関数を囲むことになりますから、
function(引数){};
の中に先程の記述を追加する事になります。すると、
のようになるので、コード自体は、
のようになります。コードの作りとしては、
の緑の部分がIDの指定で、マゼンタの部分がメソッド(関数)になります。処理については、
のようにクリックイベントに対して、関数で実装した処理を代入するような記述になりますが、この時の関数の内容も
のような形で、メソッドに対して文字列の代入をするような形になっています。C言語などもそうですが、ブロック 【 {} 】 で関数の範囲が指定されているので、その範囲に処理の記述が来る仕様になっていますが、処理単位で 【 ; 】 で開業する仕様になっています。
そして、処理の最後も 【 ; 】 が必要になる記述になっていますが、文字の入れ替えについては、このような流れになっています。
エレメント単位での処理が出来るのでテキストボックスに書いた文字列をボタンで別のエレメントに記述するようなこともできる仕様になっています。
最 新のバージョンのPython
Pythonの最新版が23日にリリースされており、2022年3月25日現在では、
■ Python 3.9.12
■ Python 3.10.4
がダウンロードできます。
■ Python