GTK# 中的菜单
最后修改于 2023 年 10 月 18 日
在本 GTK# 编程教程中,我们将学习如何使用菜单。
一个菜单栏是 GUI 应用程序中最常见的组成部分之一。它是一组位于不同菜单中的命令。虽然在控制台应用程序中,我们必须记住各种深奥的命令,但在这里,我们的大部分命令都分组到逻辑部分中。这些是公认的标准,进一步减少了学习新应用程序所需的时间。
简单菜单
在我们的第一个例子中,我们将创建一个带有一个文件菜单的菜单栏。菜单将只有一个菜单项。通过选择该项,应用程序将退出。
using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Simple menu") { SetDefaultSize(250, 200); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; MenuBar mb = new MenuBar(); Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu; MenuItem exit = new MenuItem("Exit"); exit.Activated += OnActivated; filemenu.Append(exit); mb.Append(file); VBox vbox = new VBox(false, 2); vbox.PackStart(mb, false, false, 0); Add(vbox); ShowAll(); } void OnActivated(object sender, EventArgs args) { Application.Quit(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } }
这是一个具有最小菜单栏功能的小例子。
MenuBar mb = new MenuBar();
MenuBar
控件被创建。
Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu;
顶级 MenuItem
被创建。
MenuItem exit = new MenuItem("Exit"); exit.Activated += OnActivated; filemenu.Append(exit);
退出 MenuItem
被创建并附加到文件 MenuItem
。
mb.Append(file);
顶级 MenuItem
被附加到 MenuBar
控件。
VBox vbox = new VBox(false, 2); vbox.PackStart(mb, false, false, 0);
与其他工具包不同,我们必须自己处理布局管理。我们将菜单栏放入垂直框中。

图片菜单
在下一个例子中,我们将进一步探索菜单。我们为菜单项添加图片和快捷键。快捷键是用于激活菜单项的键盘快捷键。
using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Image menu") { SetDefaultSize(250, 200); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; MenuBar mb = new MenuBar(); Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu; AccelGroup agr = new AccelGroup(); AddAccelGroup(agr); ImageMenuItem newi = new ImageMenuItem(Stock.New, agr); newi.AddAccelerator("activate", agr, new AccelKey( Gdk.Key.n, Gdk.ModifierType.ControlMask, AccelFlags.Visible)); filemenu.Append(newi); ImageMenuItem open = new ImageMenuItem(Stock.Open, agr); open.AddAccelerator("activate", agr, new AccelKey( Gdk.Key.n, Gdk.ModifierType.ControlMask, AccelFlags.Visible)); filemenu.Append(open); SeparatorMenuItem sep = new SeparatorMenuItem(); filemenu.Append(sep); ImageMenuItem exit = new ImageMenuItem(Stock.Quit, agr); exit.AddAccelerator("activate", agr, new AccelKey( Gdk.Key.q, Gdk.ModifierType.ControlMask, AccelFlags.Visible)); exit.Activated += OnActivated; filemenu.Append(exit); mb.Append(file); VBox vbox = new VBox(false, 2); vbox.PackStart(mb, false, false, 0); vbox.PackStart(new Label(), false, false, 0); Add(vbox); ShowAll(); } void OnActivated(object sender, EventArgs args) { Application.Quit(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } }
我们的例子展示了一个顶级菜单项,其中包含三个子级菜单项。每个菜单项都有一个图片和一个快捷键。退出菜单项的快捷键是有效的。
AccelGroup agr = new AccelGroup(); AddAccelGroup(agr);
为了使用快捷键,我们创建一个全局 AccelGroup
对象。它将在稍后使用。
ImageMenuItem newi = new ImageMenuItem(Stock.New, agr);
ImageMenuItem
被创建。图像来自图像库。
exit.AddAccelerator("activate", agr, new AccelKey( Gdk.Key.q, Gdk.ModifierType.ControlMask, AccelFlags.Visible));
这为退出菜单项创建了一个 Ctrl+Q 快捷键。
SeparatorMenuItem sep = new SeparatorMenuItem(); filemenu.Append(sep);
这些行创建一个分隔符。它用于将菜单项分组为逻辑组。

CheckMenuItem
一个 CheckMenuItem
是一个带有复选框的菜单项。它可用于处理布尔属性。
using Gtk; using System; class SharpApp : Window { private Statusbar statusbar; public SharpApp() : base("Check menu item") { SetDefaultSize(250, 200); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; MenuBar mb = new MenuBar(); Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu; Menu viewmenu = new Menu(); MenuItem view = new MenuItem("View"); view.Submenu = viewmenu; CheckMenuItem stat = new CheckMenuItem("View Statusbar"); stat.Toggle(); stat.Toggled += OnStatusView; viewmenu.Append(stat); MenuItem exit = new MenuItem("Exit"); exit.Activated += OnActivated; filemenu.Append(exit); mb.Append(file); mb.Append(view); statusbar = new Statusbar(); statusbar.Push(1, "Ready"); VBox vbox = new VBox(false, 2); vbox.PackStart(mb, false, false, 0); vbox.PackStart(new Label(), true, false, 0); vbox.PackStart(statusbar, false, false, 0); Add(vbox); ShowAll(); } void OnStatusView(object sender, EventArgs args) { CheckMenuItem item = (CheckMenuItem) sender; if (item.Active) { statusbar.Show(); } else { statusbar.Hide(); } } void OnActivated(object sender, EventArgs args) { Application.Quit(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } }
在我们的代码示例中,我们展示了一个复选菜单项。如果复选框被激活,则显示状态栏控件。如果不是,则隐藏状态栏。
CheckMenuItem stat = new CheckMenuItem("View Statusbar");
CheckMenuItem
控件被创建。
stat.Toggle();
Toggle
方法检查/取消选中复选菜单项。
if (item.Active) { statusbar.Show(); } else { statusbar.Hide(); }
根据 CheckMenuItem
的状态,我们显示或隐藏状态栏控件。

子菜单
我们的最后一个例子演示了如何在 GTK# 中创建子菜单。
using Gtk; using System; class SharpApp : Window { public SharpApp() : base("Submenu") { SetDefaultSize(250, 200); SetPosition(WindowPosition.Center); DeleteEvent += delegate { Application.Quit(); }; MenuBar mb = new MenuBar(); Menu filemenu = new Menu(); MenuItem file = new MenuItem("File"); file.Submenu = filemenu; // submenu creation Menu imenu = new Menu(); MenuItem import = new MenuItem("Import"); import.Submenu = imenu; MenuItem inews = new MenuItem("Import news feed..."); MenuItem ibookmarks = new MenuItem("Import bookmarks..."); MenuItem imail = new MenuItem("Import mail..."); imenu.Append(inews); imenu.Append(ibookmarks); imenu.Append(imail); // exit menu item MenuItem exit = new MenuItem("Exit"); exit.Activated += OnActivated; filemenu.Append(import); filemenu.Append(exit); mb.Append(file); VBox vbox = new VBox(false, 2); vbox.PackStart(mb, false, false, 0); vbox.PackStart(new Label(), false, false, 0); Add(vbox); ShowAll(); } void OnActivated(object sender, EventArgs args) { Application.Quit(); } public static void Main() { Application.Init(); new SharpApp(); Application.Run(); } }
子菜单创建。
Menu imenu = new Menu();
子菜单是一个 Menu
。
MenuItem import = new MenuItem("Import"); import.Submenu = imenu;
它是属于顶级文件菜单的菜单项的子菜单。
MenuItem inews = new MenuItem("Import news feed..."); MenuItem ibookmarks = new MenuItem("Import bookmarks..."); MenuItem imail = new MenuItem("Import mail..."); imenu.Append(inews); imenu.Append(ibookmarks); imenu.Append(imail);
子菜单有自己的菜单项。

在本 GTK# 编程库的这一章中,我们展示了如何使用菜单。