Go-GTK   メニュー

ホーム   Goチュートリアル


メニュー

この章では、Go-GTK のメニューバーとツールバーとステータスバーを説明します。

GTK のこれらバーは、他の GUI アプリケーション・フレームワークとは違い、次のような特徴があります。

  1. バーは、ウィンドウにではなく、Box コンテナーに含めなければなりません。
  2. メニューバーを Box コンテナーに含めても、Ubuntu の場合は、Ubuntu の仕様とおりに、ウィンドウではなくデスクトップにメニューが表示されます。
  3. Control + Q のようなショートカットキーは自動的に登録されません。


メニューバー

menubar.go


package main

import (
	"github.com/mattn/go-gtk/gtk"
	"os"
)

func main() {
	gtk	.  Init(&os.Args)
	window	:= gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window	.  SetTitle("Menu Bar")
	window	.  Connect("destroy", gtk.MainQuit)
	
	menubar	:= gtk.NewMenuBar()
	
	filemenu:= gtk.NewMenuItemWithMnemonic("_File")
	menubar	.  Append(filemenu)
	
	filesub	:= gtk.NewMenu()
	filemenu.  SetSubmenu(filesub)
	
	newmenu	:= gtk.NewMenuItemWithMnemonic("N_ew")
	openmenu:= gtk.NewMenuItemWithMnemonic("O_pen")
	savemenu:= gtk.NewMenuItemWithMnemonic("S_ave")
	filesepa:= gtk.NewSeparatorMenuItem()
	exitmenu:= gtk.NewMenuItemWithMnemonic("E_xit")
	exitmenu.  Connect("activate", func() {
		gtk.MainQuit()
	})
	filesub	.  Append(newmenu)
	filesub	.  Append(openmenu)
	filesub	.  Append(savemenu)
	filesub	.  Append(filesepa)
	filesub	.  Append(exitmenu)
	
	editmenu:= gtk.NewMenuItemWithMnemonic("E_dit")
	menubar	.  Append(editmenu)
	
	editsub	:= gtk.NewMenu()
	editmenu.  SetSubmenu(editsub)
	
	undomenu:= gtk.NewMenuItemWithMnemonic("U_ndo")
	redomenu:= gtk.NewMenuItemWithMnemonic("R_edo")
	editsepa:= gtk.NewSeparatorMenuItem()
	copymenu:= gtk.NewMenuItemWithMnemonic("C_opy")
	cutmenu	:= gtk.NewMenuItemWithMnemonic("C_ut")
	pastmenu:= gtk.NewMenuItemWithMnemonic("P_aste")
	
	editsub	.  Append(undomenu)
	editsub	.  Append(redomenu)
	editsub	.  Append(editsepa)
	editsub	.  Append(copymenu)
	editsub	.  Append(cutmenu)
	editsub	.  Append(pastmenu)
	
	textview:= gtk.NewTextView()
	frame	:= gtk.NewFrame("")
	frame	.  Add(textview)
	
	swindow	:= gtk.NewScrolledWindow(nil, nil)
	swindow	.  SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
	swindow	.  SetBorderWidth(10)
	swindow	.  AddWithViewPort(frame)
	
	vbox	:= gtk.NewVBox(false, 1)
	vbox	.  PackStart(menubar, false, false, 0)
	vbox	.  PackStart(swindow, true, true, 0)
	window	.  Add(vbox)
	
	window	.  ShowAll()
	window	.  SetSizeRequest(400, 250)
	gtk	.  Main()
}
	

実行方法

ターミナルで、menubar.go を保存したディレクトリに移動して、次のコードを実行してください。


go run menubar.go
    


実行結果


コード説明


	menubar	:= gtk.NewMenuBar()
	

メニューバーを作っています。


	filemenu:= gtk.NewMenuItemWithMnemonic("_File")
	

メニューアイテム(menu item)を作っています。アンダースコア( _ )の後の文字が、ニーモニック(mnemonic)キーになります。ニーモニックとは、オプション(option)キーと同時にそのキーを押すと、そのメニューを選んだことになるキーです。メニューには、File のように、ニーモニックキーにアンダーラインが付いて表示されます。


	filemenu:= gtk.NewMenuItemWithLabel("File")
	

上記のように記述すると、ニーモニックを使用しないメニューアイテムが作れます。


	menubar	.  Append(filemenu)
	

メニューバーに、filemenu メニューアイテムを追加しています。


	filesub	:= gtk.NewMenu()
	

ファイルメニューに、さらにメニューアイテムを追加するには、まずメニューを作ります。


	filemenu.  SetSubmenu(filesub)
	

そのメニューを、ファイルメニューのサブメニューとして設定します。


	newmenu	:= gtk.NewMenuItemWithMnemonic("N_ew")
	
そして、ファイルメニューに追加するメニューアイテムを作ります。


	filesub	.  Append(newmenu)
	

そのメニューアイテムを、サブメニューに追加します。


	vbox	.  PackStart(menubar, false, false, 0)
	

そして、メニューバーを Box コンテナーに入れます。


	window	.  Add(vbox)
	

最後に、その Box コンテナーをウィンドウに追加します。


ツールバー

toolbar.go


package main

import (
	"github.com/mattn/go-gtk/gtk"
	"os"
	"strconv"
)

func main() {
	gtk	.  Init(&os.Args)
	window	:= gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window	.  SetTitle("Tool Bar")
	window	.  SetBorderWidth(5)
	window	.  SetPosition(gtk.WIN_POS_CENTER)
	window	.  Connect("destroy", gtk.MainQuit)
	
	count	:= 5
	
	tool	:= gtk.NewToolbar()
	tool	.  SetStyle(gtk.TOOLBAR_ICONS)
	
	undo	:= gtk.NewToolButtonFromStock(gtk.STOCK_UNDO)
	redo	:= gtk.NewToolButtonFromStock(gtk.STOCK_REDO)
	sep	:= gtk.NewSeparatorToolItem()
	quit	:= gtk.NewToolButtonFromStock(gtk.STOCK_QUIT)
	
	redo	.  SetSensitive(false)
	
	tool	.  Insert(undo, 0)
	tool	.  Insert(redo, 1)
	tool	.  Insert(sep,  2)
	tool	.  Insert(quit, 3)
	
	label	:= gtk.NewLabel("")
	label	.  SetAngle(20)
	label	.  SetMarkup("<span size='19000'>5</span>")
	
	vbox	:= gtk.NewVBox(false, 5)
	vbox	.  PackStart(tool, false, false, 0)
	vbox	.  Add(label)
	window	.  Add(vbox)
	
	undo	.  Connect("clicked", func() {
		count--
		switch count {
		case 0:
			undo.SetSensitive(false)
		case 4:
			redo.SetSensitive(true)
		}
		str := "<span size='19000'>" + strconv.Itoa(count) + "</span>"
		label.SetMarkup(str)
	})
	
	redo	.  Connect("clicked", func() {
		count++
		switch count {
		case 1:
			undo.SetSensitive(true)
		case 5:
			redo.SetSensitive(false)
		}
		str := "<span size='19000'>" + strconv.Itoa(count) + "</span>"
		label.SetMarkup(str)
	})
		
	quit	.  Connect("clicked", gtk.MainQuit)
	
	window	.  ShowAll()
	window	.  SetSizeRequest(400, 250)
	gtk	.  Main()
}
	

実行方法

ターミナルで、toolbar.go を保存したディレクトリに移動して、次のコードを実行してください。


go run toolbar.go
    


実行結果


ステータスバー

statusbar.go


package main

import (
	"github.com/mattn/go-gtk/gtk"
	"os"
)

func main() {
	gtk	.  Init(&os.Args)
	window	:= gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window	.  SetTitle("Status Bar")
	window	.  SetBorderWidth(5)
	window	.  SetPosition(gtk.WIN_POS_CENTER)
	window	.  Connect("destroy", gtk.MainQuit)
	
	ok	:=  gtk.NewButtonWithLabel("OK")
	cancel	:=  gtk.NewButtonWithLabel("Cencel")
	
	hbox	:= gtk.NewHBox(true, 5)
	hbox	.  Add(ok)
	hbox	.  Add(cancel)
	
	textview:= gtk.NewTextView()
	frame	:= gtk.NewFrame("")
	frame	.  Add(textview)
	
	swindow	:= gtk.NewScrolledWindow(nil, nil)
	swindow	.  SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
	swindow	.  AddWithViewPort(frame)
	
	status	:= gtk.NewStatusbar()
	id	:= status.GetContextId("go")
	status	.  Push(id, "Ready.")
	
	ok	.  Connect("clicked", func() {
		status.Push(id, "OK was clicked.")
	})
	
	cancel	. Connect("clicked", func() {
		status.Push(id, "Cancel was clicked.")
	})
	
	vbox	:= gtk.NewVBox(false, 5)
	vbox	.  PackStart(hbox, false, false, 0)
	vbox	.  Add(swindow)
	vbox	.  PackEnd(status,false,false,0)
	
	window	.  Add(vbox)
	
	window	.  ShowAll()
	window	.  SetSizeRequest(400, 250)
	gtk	.  Main()
}
	

実行方法

ターミナルで、statusbar.go を保存したディレクトリに移動して、次のコードを実行してください。


go run statusbar.go
    


実行結果


ラジオメニューとチェックメニュー

othermenu.go


package main

import (
	"github.com/mattn/go-gtk/gtk"
)

func main() {

	gtk.Init(nil)
	
	window	:= gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window	.  SetDefaultSize(400, 250)
	window	.  SetTitle("Other Menu")
	window	.  SetPosition(gtk.WIN_POS_CENTER)
	window	.  Connect("destroy", gtk.MainQuit)
	
	vbox	:= gtk.NewVBox(false, 1)
	window	.  Add(vbox)
	
	label	:= gtk.NewLabel("")
	label	.  SetMarkup("<span foreground='red' size='19000'>Red</span>")
	vbox	.  PackEnd(label, true, true,0)
	
	//--------------------------------------------------------
	// Menu
	//--------------------------------------------------------
	menubar	:= gtk.NewMenuBar()
	vbox	.  PackStart(menubar, false, false, 0)
	
	radio	:= gtk.NewMenuItemWithMnemonic("_Radio")
	menubar	.  Append(radio)
	radiosub:= gtk.NewMenu()
	radio	.  SetSubmenu(radiosub)
	
	red	:= gtk.NewRadioMenuItemWithLabel(nil, "Red")
	green	:= gtk.NewRadioMenuItemWithLabel(red.GetGroup(), "Green")
	blue	:= gtk.NewRadioMenuItemWithLabel(red.GetGroup(), "Blue")
	
	radiosub.  Append(red)
	radiosub.  Append(green)
	radiosub.  Append(blue)
	
	red	.  Connect("activate", func() {
		if red.GetActive() {
			label.SetMarkup("<span foreground='red' size='19000'>Red</span>")
		}
	})
	
	green	.  Connect("activate", func() {
		if green.GetActive() {
			label.SetMarkup("<span foreground='green' size='19000'>Green</span>")
		}
	})
	
	blue	.  Connect("activate", func() {
		if blue.GetActive() {
			label.SetMarkup("<span foreground='blue' size='19000'>Blue</span>")
		}
	})
	
	check	:= gtk.NewMenuItemWithMnemonic("_Check")
	menubar	.  Append(check)
	checksub:= gtk.NewMenu()
	check	.  SetSubmenu(checksub)
	
	show	:= gtk.NewCheckMenuItemWithMnemonic("_Show Label")
	checksub.  Append(show)
	show	.  Connect("activate", func() {
		if show.GetActive() {
			label.Show()
		} else {
			label.Hide()
		}
	})
	show	.  SetActive(true)
	
	window  .  ShowAll()
	gtk     .  Main()
}
	

実行方法

ターミナルで、othermenu.go を保存したディレクトリに移動して、次のコードを実行してください。


go run othermenu.go
    


実行結果


ショートカットキー

Control + Q(macOSでは Command + Q)で終了(Quit)メニューを選んだことになるようなキーの組み合わせをショートカットキーと呼びます。

GTK のショートカットキーの設定方法は、他の GUI アプリケーション・フレームワークと比べるとかなり変わっています。

まず、XMLで、メニューの外枠を規定します。そしてそこからコードをゴニョゴニョしてショートカットキーを設定していきます。

action.go


package main

import (
	"github.com/mattn/go-gtk/gtk"
)

func main() {

	UI_INFO := `
<ui>
	<menubar name='MenuBar'>
		<menu action='FileMenu'>
			<menuitem action='FileNew' />
			<menuitem action='FileOpen' />
			<menuitem action='FileSave' />
			<separator />
			<menuitem action='FileQuit' />
		</menu>
		<menu action='EditMenu'>
			<menuitem action='EditUndo' />
			<menuitem action='EditRedo' />
			<separator />
			<menuitem action='EditCopy' />
			<menuitem action='EditPaste' />
			<menuitem action='EditCut' />
			<menuitem action='EditSomething' />
		</menu>
	</menubar>
	<toolbar name='ToolBar'>
			<toolitem action='FileNewTool' />
			<toolitem action='FileOpenTool' />
			<toolitem action='FileSaveTool' />
			<separator />
			<toolitem action='FileQuit' />
	</toolbar>
</ui>
`
	gtk.Init(nil)
	
	window	:= gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window	.  SetDefaultSize(400, 250)
	window	.  SetTitle("Action Menu")
	window	.  SetPosition(gtk.WIN_POS_CENTER)
	window	.  Connect("destroy", gtk.MainQuit)
	
	vbox	:= gtk.NewVBox(false, 1)
	window	.  Add(vbox)
	
	label	:= gtk.NewLabel("未選択")
	vbox	.  PackEnd(label, true, true,0)
	
	/*					*/
	/*	Action				*/
	/*					*/
	
	action	:= gtk.NewActionGroup("my_action")
	
	ui      := gtk.NewUIManager()
	ui      .  AddUIFromString(UI_INFO)
	ui      .  InsertActionGroup(action, 0)
	
	accel	:= ui.GetAccelGroup()
	window	.  AddAccelGroup(accel)
	
	/*					*/
	/*	File Menu			*/
	/*					*/
	
	action	.  AddAction(gtk.NewAction("FileMenu", "File", "", ""))

	filenew	:= gtk.NewAction("FileNew", "", "", gtk.STOCK_NEW)
	filenew	.  Connect("activate", func() { label.SetLabel("New")})
	action	.  AddActionWithAccel(filenew, "")
	//action.  AddAction(filenew) アクセルがつかない
	
	fileopen:= gtk.NewAction("FileOpen", "", "", gtk.STOCK_OPEN)
	fileopen.  Connect("activate", func() { label.SetLabel("Open")})
	action	.  AddActionWithAccel(fileopen, "")
	
	filesave:= gtk.NewAction("FileSave", "", "", gtk.STOCK_SAVE)
	filesave.  Connect("activate", func() { label.SetLabel("Save")})
	action	.  AddActionWithAccel(filesave, "")

	filequit:= gtk.NewAction("FileQuit", "", "", gtk.STOCK_QUIT)
	filequit.  Connect("activate", gtk.MainQuit)
	action	.  AddActionWithAccel(filequit, "")
	
	
	/*					*/
	/*	Edit Menu			*/
	/*					*/
	
	action	.  AddAction(gtk.NewAction("EditMenu", "Edit", "", ""))
	
	editundo:= gtk.NewAction("EditUndo", "", "", gtk.STOCK_UNDO)
	editundo.  Connect("activate", func() {label.SetLabel("Undo")})
	action	.  AddActionWithAccel(editundo, "")
	
	editredo:= gtk.NewAction("EditRedo", "", "", gtk.STOCK_REDO)
	editredo.  Connect("activate", func() {label.SetLabel("Redo")})
	action	.  AddActionWithAccel(editredo, "")

	editcopy:= gtk.NewAction("EditCopy", "", "", gtk.STOCK_COPY)
	editcopy.  Connect("activate", func() { label.SetLabel("Copy")})
	action	.  AddActionWithAccel(editcopy, "")

	editpast:= gtk.NewAction("EditPaste", "", "", gtk.STOCK_PASTE)
	editpast.  Connect("activate", func() { label.SetLabel("Paste")})
	action	.  AddActionWithAccel(editpast, "")
	
	editcut	:= gtk.NewAction("EditCut", "", "", gtk.STOCK_CUT)
	editcut	.  Connect("activate", func() { label.SetLabel("Cut")})
	action	.  AddActionWithAccel(editcut, "")

	editsome:= gtk.NewAction("EditSomething", "Something", "", "")
	editsome.  Connect("activate", func() {
		label.SetLabel("Something was selected.")
	})
	action	.  AddActionWithAccel(editsome, "<control><alt>S")
	
	
	/*					*/
	/*	Tool Bar			*/
	/*					*/
	
	new	:= gtk.NewAction("FileNewTool", "", "", gtk.STOCK_NEW)
	new	.  Connect("activate", func() { label.SetLabel("Tool New")})
	action	.  AddActionWithAccel(new, "")
	
	open	:= gtk.NewAction("FileOpenTool", "", "", gtk.STOCK_OPEN)
	open	.  Connect("activate", func() { label.SetLabel("Tool Open")})
	action	.  AddActionWithAccel(open, "")
	
	save	:= gtk.NewAction("FileSaveTool", "", "", gtk.STOCK_SAVE)
	save	.  Connect("activate", func() { label.SetLabel("Tool Save")})
	action	.  AddActionWithAccel(save, "")
	
	/*					*/
	/*	 Assembly			*/
	/*					*/
	
	menubar := ui.GetWidget("/MenuBar")
	toolbar := ui.GetWidget("/ToolBar")
	vbox    .  PackStart(menubar, false, false, 0)
	vbox    .  PackStart(toolbar, false, false, 0)
	//vbox  .  Add(label)
	
	window  .  ShowAll()
	gtk     .  Main()
}
	

実行方法

ターミナルで、action.go を保存したディレクトリに移動して、次のコードを実行してください。


go run action.go
    


実行結果



134 visits
Posted: Aug. 02, 2019
Update: Aug. 08, 2019

ホーム   Goチュートリアル   目次