python系GUIアプリケーションでのキーバインド(Tkinter編、wxPython編)
pythonでGUIプログラミングをするときのウィジットツールキットが何種類かあります。私は大抵、TkinterかwxPythonでGUIを組み立てていってます。
で、それぞれコピーペーストでよくバインドされるControl-C、Control-Vとか終了させるControl-Qを使いたい場面が多々あります。なので今回それぞれのキーバインド方法をまとめておおくことにしました。今回の例では、<Control>-Qでアプリケーションを終了させるキーバインドを設定してみます。
確認環境は、Linux Mint 18.3上でpythonのバージョンは以下になります。
hoge $ python3 --version
Python 3.5.2
Tkinter編
TkinterはPython標準のツールキットで特にライブラリを追加することもなく使うことが可能です。なのでpythonがクロスプラットフォームで使用可能な状態であればTkinterも新たにライブラリを入れること無くクロスプラットフォーム環境で使用が可能です。
キーバインドに関しても結構簡単に設定することができます。
まず、frameだけ組み立てたソースは以下になります。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# tkkeybind.py
#
from tkinter import *
from tkinter import ttk
class AppUI(Frame):
def createWidgets(self):
main_frame = Frame (root, width=400, height=300)
main_frame.pack(padx=4, pady=4)
def __init__(self, master=None):
Frame.__init__(self, master)
self.createWidgets()
root = Tk()
app = AppUI(root)
app.master.title("tkkeybind")
app.pack()
root.mainloop()
#### EOF ####
実行するとこんな感じになります。
hoge $ ./tkbind.py
このままでは、当然ですが<Control>-Qを押してもアプリケーションは終了しません。次にキーバインドしてみます。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# tkkeybind.py
#
from tkinter import *
from tkinter import ttk
class AppUI(Frame):
def createWidgets(self):
main_frame = Frame (root, width=400, height=300)
main_frame.pack(padx=4, pady=4)
def __init__(self, master=None):
Frame.__init__(self, master)
self.createWidgets()
root = Tk()
app = AppUI(root)
app.master.title("tkkeybind")
app.pack()
root.bind("<Control-q>", sys.exit)
root.bind("<Control-Q>", sys.exit)
root.mainloop()
#### EOF ####
root.bind(“<Control-q>”, sys.exit)とroot.bind(“<Control-Q>”, sys.exit)でキーバインドをしています。これで実行すると<Control>-Qを押すとアプリケーションが終了するのが確認できると思います。
wxPython編
wxPythonもクロスプラットフォームなウィジットツールキットですが各OSにpythonを入れた後にwxPythonもライブラリをpipする必要があります。個人的にですがwxPyhtonのいいところは、各OS NativeなGUIになってくれるところでMac上ではメインメニューが特に指定しないかぎりデスクトップ上部のメニューバーに構成してくれます。
今回、確認時のwxPythonは以下になります。またwxPythonでのキーバインドの方法はいろいろあるようですのでこの記事は一例として参考にしてください。
hoge $ pip show wxpython
Name: wxPython
Version: 4.1.0
Summary: Cross platform GUI toolkit for Python, "Phoenix" version
Home-page: http://wxPython.org/
Author: Robin Dunn
. . . . .
まず、tkinterのときと同様にframeの雛形を作ります。今回、雛形はwxGladeで作りました。ソースは以下になります。
余談ですがwxGladeで雛形を作ると2行目は、-*- coding: UTF-8 -*-となりますがemacsで編集するとき文句を言われるのでUTF-8の文字を小文字でutf-8に編集しなおしています。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# generated by wxGlade 0.9.4 on Mon Aug 10 13:39:28 2020
#
import wx
# begin wxGlade: dependencies
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame.__init__
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.panel_1 = wx.Panel(self, wx.ID_ANY)
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: MyFrame.__set_properties
self.SetTitle("wxkeybind")
# end wxGlade
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
# end wxGlade
# end of class MyFrame
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
# end of class MyApp
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
#### EOF ####
実行すると以下のようになります。
hoge $ wxkeybind.py
キーバインド設計を追記しいたソースは以下になります。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# generated by wxGlade 0.9.4 on Mon Aug 10 13:39:28 2020
#
import wx
import sys
# begin wxGlade: dependencies
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MyFrame.__init__
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.panel_1 = wx.Panel(self, wx.ID_ANY)
####
new_id = wx.NewId()
accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('Q'), new_id )])
self.SetAcceleratorTable(accel_tbl)
self.Bind(wx.EVT_MENU, self.OnQuit, id=new_id)
self.__set_properties()
self.__do_layout()
# end wxGlade
def __set_properties(self):
# begin wxGlade: MyFrame.__set_properties
self.SetTitle("wxkeybind")
# end wxGlade
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
# end wxGlade
def OnQuit(self, event):
self.Close()
# end of class MyFrame
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
# end of class MyApp
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
#### EOF ####
追加したところを抜粋すると def init(self, *args, **kwds):のところに
new_id = wx.NewId()
accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('Q'), new_id )])
self.SetAcceleratorTable(accel_tbl)
self.Bind(wx.EVT_MENU, self.OnQuit, id=new_id)
とdef文追加で
def OnQuit(self, event):
self.Close()
になります。これで実行すると<Contorl>-Qでアプリケーションが終了するはずですので確認してみてください。
参考にさせていただいたサイトは以下になります。
wxPython: Keyboard Shortcuts (Accelerators)
この投稿へのトラックバック
トラックバックはありません。
- トラックバック URL
この投稿へのコメント