この文書は、Dr. Corran WebsterさんによるW Widgetsの"W Reference"(http://www.nevada.edu/~cwebster/Python/WWidgets/Wreference.html)を訳したものです。
訳の公開に快く承諾してくださったDr. Corran Websterさんに感謝いたします。
内容の理解が伴っていないので、おかしいところがあるかもしれません。お気づきの点がございましたら、わたしまでお知らせいただければ幸いです。
このセクションではWウィジェットモジュールの最も重要なクラストメソッドについて説明します。(XXX 不完全なところもあります-しかしメインのウィジェットの部分についてはできています)
広いとは言いませんが、おそらくよく使うであろうという部分を説明しています。より詳しくハッキングするなら、ソースを見る必要があるでしょう。
ほとんどのウィジェットに、説明すべきたくさんの引数があります:
None
ならウィンドウのフォントが使用され、 (font, style, size, color) では、fontはフォント名、styleはテキストで使用されるスタイルのフラグ(QuickDrawモジュールの始めにリストがあります)、sizeはフォントサイズのポイント数、colorは上で述べたタプル。
[control][cmd][shift]char
ユーザの押すキー。コントロール、コマンドあるいはシフトキーで修飾されます。charは、修飾キーが押された後に実際に押される文字;shiftcでなくshiftC。あるキーはもっと親しみのある文字に翻訳される。例えば、returnはreturnkey
と呼ばれ、矢印キーはページアップ/ダウンと呼ばれます。完全なリストはWkeys
モジュールにあります。
コールバックは実際の文字を受け取り、アプリケーションのメインループから元のイベントレコードを受け取ります。
<key>
ユーザがキーを、多くの場合修飾キーとともに押すこと。
コールバックは実際の文字を受け取り、アプリケーションのメインループから元のイベントレコードを受け取ります。もし、コールバックが1を返したら、アプリケーションはそれ以上イベントを伝えない。これで、あるキー入力をブロックしたり、修飾したりできます。
<click>
ユーザがウィジェット内でクリックすること。
コールバックはクリックが発生した場所と、押された修飾キーを受け取る。コールバックが1を返したら、アプリケーションはそれ以上イベントを伝えません。
<idle>
アプリケーションがアイドリングしています。ウィジェットはこのイベントを、カーソル点滅のように定期的に送ります。
コールバックは何も引数を受け取りません。もしコールバックが1を返したら、アプリケーションはそれ以上イベントを伝えません。
<select>
ウィジェットがアクティブウィンドウで選択される、あるいは選択解除されること。
もしコールバックがウィンドウにバインドされていたら、新しいアクティブウィジェットに送られます。コールバックがウィジェットにバインドされていたら、ウィジェットが選択された、あるいは解除されたかによって1あるいは0が送られます。もしコールバックが1を返したら、それ以上の処理はブロックされ、ウィジェットは選択を拒否することができ、あるいはウィンドウがアクティブウィンドウの変更をブロックできます。
ウィジェットの抽象クラスは、直接インスタンス化するのでなく、サブクラスを作るために設計されています。これらには共通の便利な機能があります。
Widget
(possize) ウィジェットは全てのWウィジェットの起源となる基底クラス(ベースクラス)です。
ウィジェットには以下のメソッドがあります。
show
(onoff) getpossize
()getbounds
()move
(x [, y =
None
])rmove
(deltax [, deltay =
None
])resize
(possize)open
()bind
(key,
callback)forall
(methodname [,
*args
])forall_butself
(methodname
[, *args
])forall_frombottom
(methodname
[, *args
])*args
をmethodnameに適用します。最初にキーにバインドされた'<methodname>'
を探し、次にmethodnameの名前を持つ実際のメソッドを探します。forall
はおのおののサブウィジェットについてforall
を呼び出し、自分自身にmethodnameを適用します(つまり、先順横断?)。forall_frombottom
は最初に自分自身にmethodnameを適用し、それからサブウィジェットにforall_frombottom
を呼び出します(つまり、後順横断?)。forall_butself
は、サブウィジェットがあればおのおのにforall
を呼び出しますが、現在のウィジェットにはmethodnameを適用しません。
__setattr__
, __delattr__
, __setitem__
, __getitem__
および__delitem__
メソッドはサブウィジェットの処理を容易にします。
__setitem__
, __getitem__
とand __delitem__
はウィジェットのサブウィジェットディクショナリに直接影響を与えます。
__setattr__
およびand __delattr__
はWidget
インスタンスをウィジェットのサブウィジェットディクショナリに変換します。
ウィジェットのサブクラスを作る時に、メソッドをオーバーライドしたくなるかもしれません:
click
(point,
modifiers)draw
([visRgn =
None
])test
(point)close
()ベースクラスであるウィジェットクラスには存在しないメソッドがいくつかありますが、もしも加えたらWウィジェットの他の部分にフックします。
rollover
(onoff)ClickableWidget
(possize) ClickableWidgetはクリックに反応するウィジェットのベースクラスです。
ClickableWidget
は、Widget
のサブクラスです。これはさらに以下のメソッドを定義しています:
enable
(onoff)
callback
() SelectableWidget
(possize) SelectableWidgetはキーボードフォーカスを受け付けることのできるウィジェットのベースクラスです。
SelectableWidget
はWidget
のサブクラスです。これはさらに以下のメソッドを定義しています:
select
(onoff [,
isclick = 0
]) '<select>'
にバインドされたコールバックを持っていたら、このメソッドで呼び出されます。もしウィジェットが何かの理由で選択されないなら、コールバックは1を返すべきでしょう。
drawselframe
(onoff)
もしSelectableWidgetからクラスを継承するなら、たいてい以下のメソッドをオーバーライドしたいでしょう。
key
(char,
event)Evt.GetNextEvent
によって本来返されるイベントのタプルです。このメソッドは標準のキー操作に使われるでしょう;コマンドとなるキーイベントにコールバックをバインドすることが(キーのイベントを無視するために、あるいは、コマンドキーがあるかどうかをmodifiers & Events.cmdKey
がtrueかどうかで調べることができるような特別なキーの場合に)、よく行われます。
ControlWidget
(possize [,
title = "Control"
, procID =
0
, callback = None
, value =
0
, min = 0
, max =
0
]) ControlWidgetは標準のMacintoshのコントロール、例えばボタンやスクロールバーをラップするのに使われる抽象クラスです。
procIDはMacintosh toolboxのcontrol IDで、それはControls
モジュールの中に記述されています。valueはcontrolの初期値で、minはcontrolが取り得る最小値、maxは最大値です。ControlWidget
はClickableWidget
とWidget
のサブクラスで、これらのメソッドを継承しています。さらに、以下のメソッドを持っています:
open
()
Ctl.NewControl
への呼び出しを通じて、裏に潜むMacintosh controlを作成します。
enable
(onoff)
settitle
(title)
gettitle
()
もし、何か他のMacintosh control(System8で標準になったものがかなりたくさんあります)に基づいて新しいウィジェットを作りたいなら、ControlWidgetのサブクラスが必要になることも考えられます。もしそうするなら、作成したサブクラスの__init__
メソッドの中でControlWidget.__init__
を適切なProcID、value、min、maxとともに慎重に呼び出してください。これらの変数がどのように使われているか、Inside Macintoshを参照してください。さらに、以下のメソッドをオーバーライドする必要があるかもしれません:
click
(point, modifiers)Ctl.TrackControl
を呼び出します。そしてもしそれがtrueを返したら、コールバックが存在する場合はコールバックを呼び出します。controlの状態を追跡するように設定したインスタンス変数がある時、あるいはいくつかの要素からなる複雑なcontrolがある場合には、このメソッドをオーバーライドする必要があるでしょう。
ウィジェットの具体クラス(concrete class)は、そのままの形で作られ、使われるもののことです。
これらは、いろいろな標準Macintosh controlに基づくラッパーです。
Button
(possize [,
title = ""
, callback =
None
]) これは、Macintoshの標準的なプッシュボタンを作ります。
titleは、ボタンのテキストとして使われ、ウィンドウフォントで表示されます。callbackは、ボタンがenable状態でクリックされた時に呼び出されます;引数は取りません。
Button
はControlWidget
、ClickableWidget
、Widget
のサブクラスです。それらのメソッドに加えて、Button
には以下のメソッドがあります:
push
()
各ウィンドウではデフォルトボタンが設定され、厚い縁取りがされることがあります。これは、親ウィンドウで設定されます。
CheckBox
(possize [,
title = "Checkbox"
, callback =
None
, value = 0
]) これはMacintoshの標準的なチェックボックスを作ります。
titleはチェックボックスのテキストとして使われ、ウィンドウフォントで表示されます。callbackは、チェックボックスがenable状態でクリックされた時に呼び出されます;引数をひとつ取り、チェックボックスの状態がget()
で返されます。valueはチェックボックスの初期状態です。
CheckBox
はControlWidget
、ClickableWidget
、Widget
の
サブクラスです。それらのメソッドに加えて、CheckBox
には以下のメソッドがあります:
push
()
toggle
()
set
(value)
get
()
RadioButton
(possize,
title, thebuttons [, callback =
None
, value = 0
]) これはMacintoshの標準的なラジオボタンを作ります。
Titleはラジオボタンのテキストとして使われ、ウィンドウフォントで表示されます。 theButtonsは一緒にグループ化されるラジオボタンを示すリストです。 callbackは、ラジオボタンがenable状態でクリックされた時に呼び出されます;引数をひとつ取り、必ず1です(しかし、たぶんWの将来のバージョンでは0になるかもしれません)。valueはラジオボタンの初期状態です(スタート時にはひとつのグループの中でせいぜいひとつのラジオボタンが選択されているということをお忘れなく)。
RadioButton
はControlWidget
、ClickableWidget
、Widget
のサブクラスです。それらのメソッドに加えて、RadioButton
には以下のメソッドがあります:
push
()
set
(value)
get
()
ScrollBar
(possize [,
callback = None
, value = 0
,
min = 0
, max = 0
]) これは、Macintoshの標準的なスクロールバーを作ります。
callbackは、スクロールバーがenable状態でクリックされた時に呼び出されます;引数をひとつ取り、ユーザがスクロールバーのスクロールインジケータを動かしたらその設定された値を、スクロールアローのアップ、ダウン、ページアップ、ページダウンでそれぞれ'+'
, '-'
, '++'
or '--'
を返します。valueはスクロールバーの位置の初期設定値です。minはスクロールバーが取り得る最小値、maxは最大値です。
ScrollBar
はControlWidget
、ClickableWidget
、Widget
のサブクラスです。それらのメソッドに加えて、ScrollBar
には以下のメソッドがあります:
up
()
'+'
とともに呼び出すことによって、ユーザによるスクロールアローのアップボタンのクリックをシミュレートします。キーをバインドするのに適しています。
down
()
'-'
とともに呼び出すことによって、ユーザによるスクロールアローのダウンボタンのクリックをシミュレートします。キーをバインドするのに適しています。
pageup
()
'++'
とともに呼び出すことによって、ユーザによるスクロールバーのページアップのクリックをシミュレートします。キーをバインドするのに適しています。
pagedown
()
'--'
とともに呼び出すことによって、ユーザによるスクロールバーのページダウンのクリックをシミュレートします。キーをバインドするのに適しています。
set
(value)
get
()
setmin
(value)
getmin
()
setmax
(value)
getmax
()
List
(possize [, items = None
,
callback = None
, flags = 0
,
cols = 1
, typingcasesens =
0
]) これは、Macintoshの標準的なリストボックスを作ります。
Itemsは、リストボックス内に表示される項目の初期値です−リストの項目はどんなPythonオブジェクトでもよく、リストボックスの各項目はstr()
で返される最初の255文字になります。
callbackは、リストボックスがenable状態でクリックされた時に呼び出されます;引数をひとつ取り、ユーザがリストボックス上でダブルクリックすると1です。flagsは選択を示すフラグです(List
モジュールをごらんください:フラグの定数はlOnlyOne
からlNoNilHilite
までです[訳注:?])。
colsは、リストボックスの列の数です。(XXX 今のところ、1列だけしかありません。項目全てを操作するコマンドは働きません。複数の列を扱う実験的なMultiList
がサブクラスがあります。)
typingcasesensは、もし大文字/小文字にかかわりなくキー入力で項目を選択するなら0に、大文字/小文字を考慮に入れる必要があるなら1にします。
ListBox
は、SelectableWidget
、Widget
のサブクラスです。それらのメソッドに加えて、ScrollBar
には以下のものがあります:
set
(items)
get
()
setselection
(selection)
getselection
()
setselectedobjects
(objects)
getselectedobjects
()
__getitem__
、__setitem__
、
__delitem__
、__getslice__
、
__selslice__
、__len__
、append
、
remove
、index
、insert
の各メソッドを持っていて、ふつうに更新可能なリストオブジェクトとして扱われます。
標準ではなく、異なるLDEFでリストボックスを作るには、open()
を呼び出してリストウィジェットを作る前に、List
インスタンスの中のLDEF_ID
クラス変数をオーバーライドします。
TwoLineList
はList
のサブクラスで、ひとつのセルに2行表示する別種のLDEFを使用しています;これはIDEのtracebackで現れるリストです。
Movie
(possize) QuickTimeムービーのウィジェットを作ります(XXX これは実験的なもののようです−ムービーを引数として渡すことができるなんてことはないでしょう?)
Movie
はWidget
のサブクラスです。以下のメソッドが定義されています:
set
(file [, start =
0
])
get
()
getmovietitle
()
start
()
stop
()
rewind
()
ポップアップメニューには、いろいろな種類があります。
PopupWidget
(possize [,
items = []
, callback =
None
]) 小さなポップアップメニューボタンを作ります。メニューはウィジェットがクリックされた時に動的に作成されます。 幅と高さは16ピクセルです。
callbackは、メニュー項目それぞれに関連付けられたコールバックがなくても呼び出されます;選ばれたオブジェクトはコールバックに引数として渡されます。Itemsは、表示されるメニュー項目のリストです;リストの中の項目は以下のもでなければなりません:
"-"
:メニューにセパレータを設定します。
PopupWidget
のcallbackに渡されます。
PopupWidget
は、ClickableWidget
のサブクラスです。さらに以下のメソッドが定義されています:
set
(items)
get
()
PopupMenu
(possize [,
items = []
, callback =
None
]) 小さなポップアップメニューボタンを作ります。メニューは前もって作られるため、内容が静的なものに適しています。 幅と高さは16ピクセルです。
PopupMenu
はPopupWidget
のサブクラスで、同じインターフェイスを持ちます。
FontMenu
(possize,
callback) 小さなフォントポップアップメニューを作ります。幅と高さは16ピクセルです。
callbackは、メニューから選択されると呼び出されます;選ばれたフォントの名称が引数として渡されます。
FontMenu
はPopupMenu
のサブクラスで、同じインターフェイスを持ちますが、set()
は除きます。このメソッドを使うと、例外を発生します。
簡単な画像を扱うウィジェットがあります。
HorizontalLine
(possize
[, thickness = 1
]) 水平線です。
矩形の上端からpossizeで示される線を描きます。thicknessはピクセルで示される太さです。
VerticalLine
(possize [,
thickness = 1
]) 垂直線です。
矩形の左端からpossizeで示される線を描きます。thicknessはピクセルで示される太さです。
HorizontalLine
とVerticalLine
はどちらもWidget
のサブクラスです。追加のメソッドはありません。
Frame
(possize [,
pattern = Qd.qd.black
, color = (0,
0, 0)
]) 矩形です。
矩形は、パターンpatternと色colorで示されるペンで描画されます。
Frame
はWidget
のサブクラスで、さらに2つのメソッドが追加されています:
setcolor
(color)setpattern
(pattern)BevelBox
(possize [,
color = (0xe000, 0xe000, 0xe000)
]) 立体の外観を持つボックス(ベベルボックス)です。
ボックスはカラーcolor(RGBで表わします)で塗りつぶされ、Appleの「プラチナアピアランス」に合うよう、縁にハイライトがつきます。
BevelBox
はWidget
のサブクラスで、さらに1つのメソッドを持っています:
setcolor
(color)これらのウィジェットは他のウィジェットをグループ化します。
Group
(possize) これは、サブウィジェットをグループ化したウィジェットを作ります。
Group
はWidget
のサブクラス(訳注:原文subwidget)です。追加のメソッドはありません。
HorizontalPanes
(possize
[, panesizes = None
, gutter =
8
]) VerticalPanes
(possize [,
panesizes = None
, gutter =
8
]) これは、縦あるいは横の列に並んだウィジェットのグループを作ります。それぞれのウィジェットの大きさは、間にある区切りをドラッグして変えることができます。
Panesizesは、それぞれの枠の大きさの割合を示すリストで、合計が1でなくてはなりません。もし、None
なら、枠は同じ大きさになります(XXX 'division by 0 error'に出会う時を除けば。枠の大きさは__init__で設定されるので、そこでサブウィジェットがないとそうなります)。gutterは、枠と枠との間の幅の大きさです。
VerticalPane
とHorizontalPane
はWidget
のサブクラスですが、公開されて使われるメソッドの追加はありません。
これは全て、WASTEテキストエディタのラッパーです。
TextBox
(possize [,
text = ""
, align =
TextEdit.teJustLeft
, fontsettings =
None
, backgroundcolor = (0xffff, 0xffff,
0xffff)
]) スタティックテキストウィジェットを作ります。
textは表示されるテキストで、alignの形式で表示されます。
TextBox
はWidget
のサブクラスで、2つのメソッドが追加されています:
set
(text)
get
()
EditText
(possize [,
text = ""
, callback = None
,
inset = (3, 3)
, fontsettings =
None
, tabsettings = (32, 0)
,
readonly = 0
])
簡単な入力フィールドを持つエディットテキストウィジェットを作ります。もし、親ウィジェットに_barx
と_bary
というサブウィジェットがあれば、それらはウィンドウのスクロールバーとして使われます。
callbackは、テキストが変更されたら呼び出されます;引数は取りません。 insetは(h, v)のタプルで、ウィジェットと含まれる実際のテキストとの境界の余白を設定します。hは左右、vは上下の余白を示します。 tabsettingsは(size, mode)のタプルで、タブが入力された時のスペースの大きさです。もしmodeがtrueならsizeはタブの文字数で、そうでないならピクセル数です。 readonlyがtrueならテキストウィジェットはスタティック、falseなら入力可能になります。
EditText
はSelectableWidget
、Widget
のサブクラスで、これらのメソッドを継承しています。さらに以下のメソッドを定義しています:
set
(text)
get
()
EditTextは、Cut、Copy、Paste、Clear、Undo/Redo、Select Allのメニューアイテムのコールバックを持っています。
TextEditor
(possize [,
text = ""
, callback = None
,
wrap = 1
, inset = (4, 4)
,
fontsettings = None
, tabsettings =
(32, 0)
, readonly = 0
]) 相当な量のテキストを編集するためのテキストエディタウィジェットを作ります。
引数は、wrapを除いてEditText
のものと同じです。
wrapはテキストの行がウィジェットで囲まれるかどうかを設定します。
TextEditor
はEditText
、SelectableWidget
、Widget
のサブクラスで、それらのメソッドを継承しています。独自の公開されたメソッドは定義されていません。
PyEditor
(possize [,
text = ""
, callback = None
,
inset = (4, 4)
, fontsettings =
None
, tabsettings = (32, 0)
,
readonly = 0
, debugger =
None
, file = ''
]) デバッガーと結び付いた、特別のPythonのソースコードのためのエディットウィジェットを作ります。
引数は、debuggerとfileを除いてTextEditorと同じです。 debuggerはコードを実行するときにデバッガーを使用するかどうか指定し、 fileはソースコードのファイルで、デバッガーが参照します。
追加のメソッドは以下のとおりです。
PyEditorは、Shift Left、Shift Right、Comment、Uncommentのメニューアイテムのコールバックを持っています。
Window
(possize [,
title = ""
, minsize = None
,
maxsize = None
, tabable =
1
, show = 1
, fontsettings =
None
])標準的なドキュメントウィンドウを作ります。
titleは、ウィンドウの上部に示されるテキストです。 minsizeとmaxsizeはそれぞれウィンドウがとりうる最小、最大の大きさです。 tabableがtrueなら、"Tab"が押されるとウィンドウ内のSelectableWidgetを順に選択し、"Shift-Tab"が押されると逆順で選択されます。もしshowがtrueなら、ウィンドウが作られた時に表示されます。
Window
は、SelectableWidget
、Widget
のサブクラスです;また、FrameWork.Window
クラスのサブクラスでもあります。さらに以下のメソッドが定義されています:
settitle
(title)
gettitle
()
getcurrentwidget
()setdefaultbutton
([button
= None
, *keys
])Button
クラスのインスタンスでなければなりません。Button
のpush()
メソッドは、"return"、"enter"、そして他のどんなキーでも*keys
パラメーターで設定できます。
さらに、ウィンドウメソッドでは、"Close"メニューアイテムのハンドラが設定されています。
どんな重要なアプリケーションでも、おそらく__init__
メソッドをオーバーライドしてセットアップしたり(Window.__init__
を呼び出して通常のセットアップをすることができます)、
close
をオーバーライドしてドキュメントがセーブされているかどうか確かめたり、ユーザに尋ねたりしたいでしょう。また、ドキュメントの操作にdomenu_menuitem
ハンドラを設定したいこともあるでしょう。データが内部に記憶されているなら、ドキュメントウィンドウクラスはドキュメントに対する操作コマンドを加えるのにも適したところです。
Dialog
(possize [,
title = ""
])
標準のモードレスダイアログボックスを作ります。これは、EasyDialogs
モジュールよりも複雑なダイアログボックスを扱います。
titleはダイアログボックスのタイトルです。
Dialog
は"Close"メニューアイテムをdisableにします(つまり、close()
メソッドを呼び出すことによって明示的に閉じられなければなりません)が、そういった点ではWindow
と同じで、Dialog
はWindow
のサブクラスです。
ダイアログは実際のところ、モードレスダイアログの枠をもった普通のウィンドウです;
Dialog Managerのルーチンは使いませんし、ユーザ定義のダイアログアイテムは'DLOG'
リソースよりもむしろゼロから作られるべきでしょう。'DLOG'
リソースを使ったダイアログには、
FrameWork.Dialog
を使ってください。
ModalDialog
(possize [,
title = ""
])モーダルダイアログボックス(ユーザが応答するまで通常の処理を停止するダイアログ)を作ります。
引数はDialog
と同じです。もしtitle
が空なら固定されたダイアログボックスのウィンドウが作られ、そうでないなら移動可能なウィンドウが作られます。ModalDialog
はDialog
のサブクラスです。
Dialog
のように、ModalDialog
はダイアログの枠を持った普通のウィンドウです。
モーダルな動作は、ModalDialog
自身が持つイベントループによって行われます。
Menuクラスは、本質的にFrameWorkモジュールのMenuクラスと同じもので、同様にFrameWorkモジュールはMenu toolboxモジュールのオブジェクトのラッパーです。
MenuBar
とMenu
は、Wapplication
モジュールと、
FrameWork
モジュール内のMenuItem
にあります。
Menu
モジュールとMenu
クラスの間の名前の衝突の可能性がありますので、注意してください。
MenuBar
()メニューバーです。
一般にはこれを作る必要はありません;アプリケーションのデフォルト動作で初期化の際にAppleメニューとともにこれをひとつ作りますし、アプリケーションのmenubarのインスタンス変数を通してこれが得られます。
MenuBar
によって定義されたメソッドは公開されていません:
MenuBar
やMenu
のサブクラスを作らないかぎり、しなければならないのはアプリケーションのメニューバーインスタンスの跡をたどることだけです。
Menu
(self,
menubar, title [, where =
0
])標準的なMacintoshのメニューを作り、メニューバーに組み込みます。
メニューはタイトルtitleを持ち、メニューバーmenubarに組み込みます。 パラメータwhereはメニューバーのどこにメニューが組み込まれるかを設定します;0なら最後に、 -1なら表示されませんがサブメニューあるいはポップアップメニューとして保持されます。
MenuItem
(menu,
title, [shortcut = None
,
callback = None
])RadioItem
(menu,
title, [shortcut = None
,
callback = None
])CheckItem
(menu,
title, [shortcut = None
,
callback = None
])メニューの中にアイテムを作り、メニューの中に組み込みます。 (XXX RadioItemとCheckItemは作動しません。)
メニューアイテムは、呼び出し可能なcallbackに渡されるか、アプリケーション、 最前面のウィンドウあるいは現在のウィンドウの選択されたウィジェットのどちらかで'domenu_callback'メソッドを持つもの、これらのうちのどれかに渡されなければなりません;そうでないならメニューは暗くなります。 メニュー項目のうち、値や実行するのが適切かどうかがアプリケーションやドキュメントの現在の状態に依存するものがあれば、'can_callback'メソッドを設けるべきです;もしこのメソッドがfalseを返したら、メニュー項目は暗くなり、trueを返したら実行可能になります。もしそういうことが必要であれば、'can_callback'メソッドはメニューアイテムのテキストを変える責任を持ちます。