PyGTKで、ショートカットキーにより、テキストラベルに関連付けた別のウィジェットをフォーカスする
GTK+では、1行テキスト入力ボックス(gtk.Entry)の隣に説明の文字列(gtk.Label)を配置するようなときに、この入力ボックスをフォーカスするためのショートカットキーをラベルのほうに表示*1し、Altキーを押しながら指定されたキーを押すことで対象のGUI部品(ウィジェット)がフォーカスされるようにすることが比較的簡単に行える。
例(Gladeを使用しない場合)
[任意]ファイル名: mnemonictest.py
#! /usr/bin/python # -*- encoding: utf-8 -*- import sys import os try: import pygtk pygtk.require("2.0") except: pass try: import gtk except: sys.exit(1) class PyGTKMnemonicTest: """ ニーモニック・ウィジェットのテスト """ def __init__(self): # ウィンドウ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("mnemonic widget test") # ショートカットキー(アクセラレータ) self.accelgroup = gtk.AccelGroup() self.window.add_accel_group(self.accelgroup) # メニューバー項目 self.menuitem = gtk.MenuItem("_File", True) self.imagemenuitem = gtk.ImageMenuItem(gtk.STOCK_QUIT, self.accelgroup) self.gtkmenu = gtk.Menu() self.gtkmenu.add(self.imagemenuitem) self.menuitem.set_submenu(self.gtkmenu) self.menubar = gtk.MenuBar() self.menubar.append(self.menuitem) # このテストのメイン部分 # ラベルとテキスト・エントリのペア(水平ボックスでまとめる)を2つ作り # 垂直ボックスでメニューと一緒にまとめる self.entry1 = gtk.Entry() self.entry1.set_text("Alt + L") self.entry2 = gtk.Entry() self.entry2.set_text("Alt + M") # コンストラクタで文字列指定をしてset_use_underline()を呼ぶ self.label1 = gtk.Label("_label") self.label1.set_use_underline(True) # 下線をニーモニックウィジェットのために使用 self.label1.set_mnemonic_widget(self.entry1) # コンストラクタでの文字列指定 + set_use_underline()の代わりに # set_markup_with_mnemonic()も使用できる self.label2 = gtk.Label() self.label2.set_markup_with_mnemonic("markup with _mnemonic") self.label2.set_mnemonic_widget(self.entry2) # 以下はレイアウト構成 self.hbox1 = gtk.HBox(False, 0) # ラベルとエントリを横に並べる self.hbox1.pack_start(self.label1, False, False, 0) self.hbox1.pack_start(self.entry1, True, True, 0) # エントリを最大化 self.hbox2 = gtk.HBox(False, 0) self.hbox2.pack_start(self.label2, False, False, 0) self.hbox2.pack_start(self.entry2, True, True, 0) # ウィンドウ全体を縦に分割 self.vbox = gtk.VBox(False, 0) self.vbox.pack_start(self.menubar, False, True, 0) self.vbox.pack_start(self.hbox1, True, True, 0) self.vbox.pack_start(self.hbox2, True, True, 0) self.hbox1.set_border_width(10) self.hbox2.set_border_width(10) self.window.add(self.vbox) # シグナルを手動で接続 self.imagemenuitem.connect("activate", gtk.main_quit) self.window.connect("delete_event", gtk.main_quit) # 表示 self.window.show_all() def main(self): gtk.main() if __name__ == "__main__": app = PyGTKMnemonicTest() app.main()
動作
この例では、2つの「テキストラベル(文字列)とテキスト入力ボックス(テキストエントリ)」のペアがウィンドウ上に配置されていて、上のラベルでは「l」、下のラベルでは「m」にそれぞれ下線が付いている。
上下それぞれのペアでラベルとエントリは対応付けられていて、
- Alt+Lで上のテキストエントリ
- Alt+Mで下のテキストエントリ
がそれぞれフォーカスされるようになっている。
関連付け方
上と下のペアでは、少しだけ違った手順をとっている。
上のほうでは、ラベルの文字列をコンストラクタ引数から指定*2後、gtk.Labelオブジェクトのメンバ関数set_use_underline()で下線をアクセラレータキーとして使用するように指示している。
下では、set_markup_with_mnemonic()関数に(下線を含んだ)文字列を渡している。この場合はset_use_underline()は不要。
そのどちらかを行った状態でメンバ関数set_mnemonic_widget()に対象ウィジェットのオブジェクトを渡すことで、関連付けが完了する。