Pythonでデスクトップアプリを開発するために、TkinterやKivy、PyQt、wxPythonの4つから使いやすいかどうか調べてみました。
アプリケーションの作成するために、ラベルや文字、ボタンの設置はカンタンにできるのか実際に試しました。
この記事では作成した画面結果をWindowsとMacで表示しています。
Tkinterについて
TkinterはPythonで標準のライブラリで、インストールする必要はありません。
Unixプラットフォームのほかにも、Windowsでも利用できます。
Ttkというサブモジュールも含まれており、GUIの操作を柔軟に対応することができます。
Tkinterのインストール確認
Tkinterは標準モジュールのため、インストールする必要はありません。
しかし、正しくインストールされているか確認はしてみましょう。
下記のコマンドで確認することができます。
$ python -m tkinter
Windowsで実行すると問題ありませんでした。
Macだとボタンの文字が無い状態で表示されました。
バージョンの問題なのかな?
画面の作成
デスクトップで動く画面の作成を行います。
from tkinter import Tk
app = Tk()
app.title('デスクトップアプリ')
app.geometry('300x300')
app.mainloop()
tkinterのTkをインポートします。
Tkオブジェクトを使って、タイトルと画面のサイズを設定しています。
画面のサイズは、xを使って縦と横の画面を設定しています。
mainloopを使って、アプリケーションを終了しないようにしています。
これがないとアプリがすぐに終了します。
Windowsの結果とMacの結果は下記になります。
テキストの追加
アプリケーションにテキストを追加します。
ここでtkinterのラベルではなく、ttkのラベルを利用してみます。
from tkinter import Tk
from tkinter.ttk import Label
app = Tk()
app.title('デスクトップアプリ')
app.geometry('300x300')
label = Label(app, text='Hello World')
label.pack()
app.mainloop()
WindowsとMacの結果は下記になります。
この状態だと、ttkを使う意味がありません。
ttkはスタイルを分けて指定することができ、分けることでコードの管理がしやすくなります。
ttkとtkinterのLabelでは、スタイルの書き方が違います。
下記は、tkinterのラベルのスタイルを設定しています。
label = Label(app, text='Hello World', fg="black", bg="blue")
引数にfgとbgをつけて、カラーを設定しています。
ttkの場合は、スタイルを設定します。
style = Style()
style.configure("BW.TLabel", foreground="black", background="blue")
label = Label(app, text='Hello World', style="BW.TLabel")
BWはなんでもいいです。
とりあえず、プレフィックスとTLabelの構成で記載すると動きます。
下記は、ラベルごとにスタイルを指定する方法です。
from tkinter import Tk
from tkinter.ttk import Label, Style
app = Tk()
app.title('デスクトップアプリ')
app.geometry('300x300')
style = Style()
style.configure("Sample.TLabel", foreground="green", background="#0F0000")
label = Label(app, text='Hello World', style="Sample.TLabel")
label.pack()
style2 = Style()
style2.configure("Sample2.TLabel", foreground="white", background="#C05000")
label2 = Label(app, text='Hello World', style='Sample2.TLabel')
label2.pack()
app.mainloop()
TtkをMacで試しているのですが、背景色のバグなのかうまく表示できないです。
Windowsは特に問題なく動作しています。
文字や背景色は、HTMLのカラーコードを指定することができます
ボタンの追加
tkinterとttkの方法でボタンを追加してみます。
使い方はラベルと同じで、カンタンです。
import tkinter
from tkinter import Tk
from tkinter.ttk import Style, Button
app = Tk()
app.title('デスクトップアプリ')
app.geometry('300x300')
style = Style()
style.configure("Sample.TButton", foreground="green", background="#0F0000")
btn = Button(app, text='Button1', style="Sample.TButton")
btn.pack()
style2 = Style()
style2.configure("Sample2.TButton", foreground="#8b4513", background="#ff69b4")
btn2 = Button(app, text='ボタン2', style='Sample2.TButton')
btn2.pack()
btn3 = tkinter.Button(text='ボタン3', fg='#cf57a9', bg='#00008b')
btn3.pack()
app.mainloop()
ほとんどラベルと同じで、LabelをButtonに変更しただけです。
スタイルの指定方法で、TLabelからTButtonに変わります。
WindowsとMacの結果は下記になります。
Labelと同じ様にTtkのスタイルがバグっています。
WindowsとMacで背景色などの表示がおかしいです。
tkinterもMacだと装飾にバグなのか表示されません。
Kivyについて
KivyはAndroidやiOS、Linuxといったクロスプラットフォームで動くPythonのソフトウェアライブラリです。
マルチタッチアプリなどの開発を行う際に、迅速に開発することができます。
Kivyが対応しているOSは下記になります。
対応OS
- Windows
- OS X
- Linux
- RPi
- Android
- iOS
Kivyのインストール
Kivyをインストールするには、pipコマンドを利用します。
しかし、対応していないバージョンなどではソースからインストールする必要がある様です。
下記コマンドは、pipやsetuptools、vertualenvをアップグレードまたはインストールを行うコマンドです。
入っていなければ実行してください。
$ python -m pip install --upgrade pip setuptools virtualenv
次にPythonのvirtualenvの環境を作成します。
$ python -m virtualenv kivy_venv
実行した場所で、kivy_venvが作成されます。
ここまでは、WindowsやMac、Linuxでも同じ操作になります。
ここからはWindowsやLinuxで環境の反映が変わってきます。
WindowsのCMDの場合は、下記になります。
kivy_venv\Scripts\activate
LinuxやMacの場合は、下記になります。
$ source kivy_venv/bin/activate
毎回実行しないといけないみたいですが、めんどくさい場合は.bashrcや.bash_profileとかに読み込む様にしておけば良いと思います。
私は、direnvをインストールしてディレクトリに移動したら実行される様にしたりします。
Kivyのインストール準備が整ったので、インストールを実行します。
$ python -m pip install kivy[base] kivy_examples
condaによるインストールは下記になります。
$ conda install kivy -c conda-forge
画面の作成
kivyで画面を作成します。
Appクラスを呼び出して、run関数で実行するだけで画面が作成されます。
from kivy.app import App
app = App()
app.title = 'サンプル'
app.run()
ターミナルにtitleを入れたかったので、4行目で行なっています。
WindowsとMacの結果は下記になります。
どちらもターミナルのタイトルが文字化けしていないので、日本語化がうまくいってますね。
以前は日本語かがうまくできておらず、どうしようもなかったのですがボタンやテキストもいけそうな感じがしますね。
テキストの追加
テキストの追加を試してみます。
Labelを追加する場合、日本語の対応をするにはフォントの設定を行わなければいけません。
今回は、WindowsとMacでフォントの場所が違うので、条件式によってフォントの指定を変えています。
ほかにも継承させてることで、buildの中にラベルの設定を行なっています。
app = App()だとwidgetを追加することができず、設定することができませんでした。
import os.path
import platform
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
self.title = 'サンプル'
pf = platform.system()
if pf == 'Windows':
fpath = ['C://', 'Windows', 'Fonts', 'meiryo.ttc']
elif pf == 'Darwin':
fpath = ['/', 'System', 'Library', 'Fonts', 'ヒラギノ明朝 ProN.ttc']
label = Label(text='Hello World あいうえお', font_name=os.path.join(*fpath))
return label
MyApp().run()
12から15行目で、フォントのパスを設定しています。
17行目でラベルの設定を行なっています。
フォントの設定をするには、引数にfont_nameをつけます。
font_nameの引数にos.path.joinを使っているのは、マルチプラットフォーム対応のパスを作るためです。
WindowsとMacやLinuxでは、パスの区切り文字が違うためです。
WindowsとMacの結果は下記になります。
どちらも文字化けが起こらずに、表示されました。
-
python kivyでラベル表示
Relative Layout以外のレイアウトについては書いてきたので、ラベルやボタンについて書いていきます。今回はラベルについて書きます。 実装 実装するために、main.pyというファイルを作成します。 ソースコード '' ...続きを見る
ボタンの追加
ボタンの追加もラベルと同じで、Labelをボタンに変更しているだけです。
import platform
from kivy.app import App
from kivy.uix.button import Button
class MyApp(App):
def build(self):
self.title = 'サンプル'
pf = platform.system()
if pf == 'Windows':
fpath = ['C://', 'Windows', 'Fonts', 'meiryo.ttc']
elif pf == 'Darwin':
fpath = ['/', 'System', 'Library', 'Fonts', 'ヒラギノ明朝 ProN.ttc']
button = Button(text='Hello World あいうえお', font_name=os.path.join(*fpath))
return button
MyApp().run()
ボタンの動作がわかりづらかったので、WindowsとMacの結果をビデオキャプチャにしました。
画面全体がボタンとして認識しているので、クリックした場合には水色で光ります。
下記で、Kivyのボタンに関する解説を行なっています。
-
python kivy ボタンの表示
今回はpythonのkivyのラベルに引き続きボタンの表示について書いていきます。 動き的には、HTMLや他のアプリとかと同じ動きになります。 実装 main.pyというファイル名で実装します。 ソースコード ''' ...続きを見る
PyQtについて
PyQtとは、クロスプラットフォームなGUIアプリケーションを作成するツールキットです。
QtをバインディングしてPython用にしたのがPyQtになります。
PyQtでは、QtがサポートしているWindowsやMacOS、Linux、iOS、Andoridで実行することができます。
ただ、ドキュメントが全て英語で書かれているため、英語が苦手な場合はツラいです。
PyQtのインストール
PyQtをインストールするには、pipコマンドを利用してインストールします。
$ pip install PyQt6
今回は、PyQt6をインストールしています。
インストールが完了すると下記のようにSuccessfullyと表示されれば問題ありません。
Collecting PyQt6
Downloading PyQt6-6.1.1-cp36.cp37.cp38.cp39-abi3-macosx_10_14_intel.whl (5.8 MB)
|████████████████████████████████| 5.8 MB 2.4 MB/s
Collecting PyQt6-sip<14,>=13.1
Downloading PyQt6_sip-13.1.0-cp39-cp39-macosx_10_9_x86_64.whl (56 kB)
|████████████████████████████████| 56 kB 19.8 MB/s
Collecting PyQt6-Qt6>=6.1.1
Downloading PyQt6_Qt6-6.1.2-py3-none-macosx_10_14_intel.whl (29.6 MB)
|████████████████████████████████| 29.6 MB 17.4 MB/s
Installing collected packages: PyQt6-sip, PyQt6-Qt6, PyQt6
Successfully installed PyQt6-6.1.1 PyQt6-Qt6-6.1.2 PyQt6-sip-13.1.0
Windowsでも実施してみましたが特に問題なくインストールできました。
インストール結果も同じ内容になっています。
画面の作成
PyQtで画面の作成をしてみます。
ドキュメントを読んだのですが、カンタンに作成できる様なサンプルを探すことができなかったので参考程度に書きました。
import sys
from PyQt6.QtWidgets import QApplication, QWidget
class Disp(QWidget):
def __init__(self, parent=None):
super(Disp, self).__init__()
self.setGeometry(500, 500, 400, 250)
self.setWindowTitle('テスト Qt')
app = QApplication(sys.argv)
disp = Disp()
disp.show()
sys.exit(app.exec())
13行目でアプリケーションを実行するしています。
16行目でアプリケーションの終了があった場合に、プログラムを終了する仕組みになっています。
6行目にあるDispクラスは何をやっているかというと、単純にタイトルの設定と画面の大きさと表示する位置について設定しています。
そのため、15行目のshowメソッドで表示を実行している形になります。
setGeometryの引数では第1と第2は座標を表しており、第3と第4は横と縦のディスプレイの長さになります。
下記はWindowsとMacの画面作成結果になります。
テキストの追加
QLabelを使って、テキストを追加してみます。
ソースは、画面作成で利用したものに追加します。
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QLabel
class Disp(QWidget):
def __init__(self, parent=None):
super(Disp, self).__init__()
label = QLabel(self)
label.setText("テストラベル")
self.setGeometry(500, 500, 400, 250)
self.setWindowTitle('テスト Qt')
app = QApplication(sys.argv)
disp = Disp()
disp.show()
sys.exit(app.exec())
Dispクラスの中にある、10行目と11行目を今回追加しています。
QLabelにQWidgetを入れて、setTextメソッドでラベルを設定するだけです。
下記が、WindowsとMacの結果になります。
Kivyでは日本語を表示するためにFontの設定が必要でした。
しかしPyQtでは特に行うことがなく、文字化けもせずに表示することができました。
ボタンの追加
PyQtではボタンを表示するには複数ありますが、今回は通常のボタンのQPushButtonを使ってみます。
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QPushButton
class Disp(QWidget):
def __init__(self, parent=None):
super(Disp, self).__init__()
QLabel("テストラベル", self)
btn = QPushButton("押す", self)
btn.setGeometry(100, 100, 100, 50)
self.setGeometry(500, 500, 400, 250)
self.setWindowTitle('テスト Qt')
app = QApplication(sys.argv)
disp = Disp()
disp.show()
sys.exit(app.exec())
12・13行目が今回追加した部分になります。
Geometryを利用しないと、「テストラベル」と被ってしまうので注意が必要です。
WindowsとMacの結果は下記になります。
使い方についてはラベルと同じなのでカンタンです。
wxPythonについて
wxPythonは、PyQtやKivyと同じくクロスプラットフォームなGUIツールキットです。
違いは、AndroidまたはiOSについては利用できません。
利用できるのは、WindowsやMacOS、LinuxおよびUnix系のOSになります。
wxPythonのインストール
インストールするには、pipコマンドを利用します。
下記のコマンドは、WindowsとMacOS用になります。
$ pip install -U wxPython
UnbuntuやMintだと下記のコマンドになります。
$ pip install -U \
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-16.04 \
wxPython
画面の作成
wxPythonを利用して画面の作成を行います。
コードは下記になります。
import wx
class Frm(wx.Frame):
def __init__(self, *args, **kw):
super(Frm, self).__init__(*args, **kw)
app = wx.App()
frm = Frm(None, title='テスト wxPython')
frm.Show()
app.MainLoop()
Frmというクラスを作って、第2引数にタイトルをセットしています。
実際に実行すると、Windowsでは問題なく表示できました。
しかしMacでは下記のエラーが表示されました。
This program needs access to the screen. Please run with a
Framework build of python, and only when you are logged in
on the main display of your Mac.
調べると、Framework build用のPythonが必要とのことです。
pyenvのバージョン管理ツールを使って入れていたのですが、どうやらpyenvではオプションが足りない様です。
pyenvの場合は、下記のコマンドで環境変数をセットする必要があります。
$ env PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install pythonのバージョン
pyenvで再インストールし直して、再度実行すると表示することができました。
テキストの追加
テキストラベルを追加する場合は、StaticTextを利用して追加します。
画面作成で使ったソースコードを利用して、テキストの追加を行います。
import wx
from wx import StaticText
class Frm(wx.Frame):
def __init__(self, *args, **kw):
super(Frm, self).__init__(*args, **kw)
StaticText(self, label='テスト wxPython')
app = wx.App()
frm = Frm(None, title='テスト wxPython')
frm.Show()
app.MainLoop()
8行目のStaticTextでラベルの追加を行なっています。
戻り値もあるのですが、今回利用していないので省いています。
戻り値を使って、フォントやサイズを変更することもできます。
WindowsとMacでの結果は下記になります。
PyQtと同じくフォントの設定を行わなくても、文字化けしないです。
Kivyも同じ様にして欲しいですね。
ボタンの追加
ボタンの追加は、Buttonを利用して追加します。
ボタンも同じく、テキストで利用したソースコードを使って試します。
import wx
from wx import StaticText, Button, Point
class Frm(wx.Frame):
def __init__(self, *args, **kw):
super(Frm, self).__init__(*args, **kw)
StaticText(self, label='テスト wxPython')
pos = Point(50, 30)
Button(self, label='押忍', pos=pos)
app = wx.App()
frm = Frm(None, title='テスト wxPython')
frm.Show()
app.MainLoop()
追加したのは、9行目と10行目になります。
9行目では、StaticTextと同じ位置で表示が被ってしまいます。
そのため、Pointを利用して位置を設定します。
10行目でボタンを追加していますが、引数として先ほど作成したPointをposという引数で設定することで位置を設定しています。
Buttonの戻り値で表示位置の設定はできない
WindowsとMacの表示結果は下記になります。
まとめ
Pythonを使って、デスクトップアプリを構築するために4つのモジュールを利用してみました。
利用してみて、見えてきたのはKivyの日本語を使うため毎回フォントのセットするのめんどくさい事がわかりました。
やり方次第だと思いますが、それでもPyQtやwxPythonではその処理が無いのでオススメです。
AndroidやiOSを含めた開発をするならPyQt一択な気もします。
でもMacとWindowsはwxPythonを使って、AndroidとiOSはXamarinもアリですね(工数は増えますが)。
書き方的には、どのモジュールも同じ様な書き方なので、ぜひ使いやすいものを選んでください。
私的には、wxPythonが使いやすそうな感じがしています。