“菜单”(menubar)和“工具栏”(toolbars)

“菜单” (menubar)和“工具栏”(toolbars)

在这个部分的GTK+程序设计教程中,我们使用“菜单”和“工具栏”。

“菜单”( menubar) 是GUI程序中最为常见的部分之一。各种各样的命令和功能都可以借以“菜单”来实现。 当我们习惯在终端(console)中启动应用程序的时候,必须要记得很多复杂的命令和参数 ,在本章节中我们将 这一切都转化为可见的操作。菜单和工具栏中标准化的操作,将让你摆脱学习新软件所耗费的大量时间和精力。

简单的菜单示列

在我们的第一个例子中,我们将生成一个含有文件菜单的菜单栏。文件菜单将只有一个菜单条(menu item)。如果点击这个菜单条程序将退出。

#include <gtk/gtk.h>int main( int argc, char *argv[])
{GtkWidget *window;GtkWidget *vbox;GtkWidget *menubar;GtkWidget *filemenu;GtkWidget *file;GtkWidget *quit;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);gtk_window_set_title(GTK_WINDOW(window), "menu");vbox = gtk_vbox_new(FALSE, 0);gtk_container_add(GTK_CONTAINER(window), vbox);menubar = gtk_menu_bar_new();filemenu = gtk_menu_new();file = gtk_menu_item_new_with_label("File");quit = gtk_menu_item_new_with_label("Quit");gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu);gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit);gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file);gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3);g_signal_connect_swapped(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);g_signal_connect(G_OBJECT(quit), "activate",G_CALLBACK(gtk_main_quit), NULL);gtk_widget_show_all(window);gtk_main();return 0;
}

生成一个菜单栏的确会让人有点疑惑。我们要牢记的是一个菜单栏和一个菜单都是源属于同一个构件的,也就是菜单外壳(menu shell)。菜单选项(menu items )是一个只对菜单有效的子构件。他们通常用来实现子菜单。

menubar = gtk_menu_bar_new();
filemenu = gtk_menu_new();

在上面的代码中我们生成了一个菜单栏构件(menubar)和一个菜单构件(menu)。

gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu);

上面的代码就会生成一个名为“文件”的菜单。这也就是说其实菜单栏就是一个菜单外壳。很显然这里的文件菜单也是一个菜单外壳。这就是为什么我们把文件菜单称为子菜单或者说是一个子外壳。

gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file);

菜单选项由函数 gtk_menu_shell_append() f来实现。然后一般情况下菜单选项被填加进菜单外壳里。 在我们的这个例子中,“quit”菜单选项是被填加进“file”菜单栏里,然后类似的是“file”菜单选项被填加进菜单中(menubar)。

g_signal_connect(G_OBJECT(quit), "activate",G_CALLBACK(gtk_main_quit), NULL);

当你单击“quit”菜单按钮,程序就会退出。

Figure: Simple menu

图象菜单, mnemonics &accelerators

在接下来的这个例子中,我们将更进一步的去探索,在GTK+系统中我们可以应用的功能。Accelerators 是快捷键的意思,用来方便的用键盘上的组合键激活一个菜单选项。 Mnemonics也是是快捷键用于用于GUI的基础。他们的具体表现都为带有下画线的字符。(译者:似乎说的不清楚啊,呵呵。具体的区别还是请参见下面的具体代码实现以及对应的程序效果图)

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>int main( int argc, char *argv[])
{GtkWidget *window;GtkWidget *vbox;GtkWidget *menubar;GtkWidget *filemenu;GtkWidget *file;GtkWidget *new;GtkWidget *open;GtkWidget *quit;GtkWidget *sep;GtkAccelGroup *accel_group = NULL;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);gtk_window_set_title(GTK_WINDOW(window), "menu");vbox = gtk_vbox_new(FALSE, 0);gtk_container_add(GTK_CONTAINER(window), vbox);menubar = gtk_menu_bar_new();filemenu = gtk_menu_new();accel_group = gtk_accel_group_new();gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);file = gtk_menu_item_new_with_mnemonic("_File");new = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);open = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL);sep = gtk_separator_menu_item_new();quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, accel_group);gtk_widget_add_accelerator(quit, "activate", accel_group, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu);gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), new);gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), open);gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), sep);gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit);gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file);gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3);g_signal_connect_swapped(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);g_signal_connect(G_OBJECT(quit), "activate",G_CALLBACK(gtk_main_quit), NULL);gtk_widget_show_all(window);gtk_main();return 0;
}

在上面的整个代码程序中,向大家展示了是如何向一个菜单选项中去填加一个图象的。当然也包括了如何使用accelerator 以及 mnemonics 。

accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
...
quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, accel_group);
gtk_widget_add_accelerator(quit, "activate", accel_group, GDK_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);

一个 accelerator 组有好多个accelerators快捷键。这里我们生成了一个“Ctrl + q” accelerators快捷键。

file = gtk_menu_item_new_with_mnemonic("_File");

我们需要调用函数 gtk_menu_item_new_with_mnemonic() 来生成一个mnemonic快捷键。你可以按下键盘上的“ Alt + F”就可以看到. mnemonic快捷键的效果。

new = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL);
open = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL);

在上面的代码中我们生成了两个带有图象的菜单选项。在所调用的函数的第二个参数中,我们设置为NULL,这样达到的效果是我们自动生成了accelerators快捷键。我们也为菜单选项分别提供了图象与文字。

sep = gtk_separator_menu_item_new();

菜单选项能够被一个水平的分割线隔开。这样的话我们就可以从逻辑上把一些菜单选项给区分开来。

Figure: Menu example

选择(Check)菜单选项 (menu item)

GtkCheckMenuItem 便是一个可以生成带有选择的菜单选项。

#include <gtk/gtk.h>void toggle_statusbar(GtkWidget *widget, gpointer statusbar)
{if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {gtk_widget_show(statusbar);} else {gtk_widget_hide(statusbar);}
}int main( int argc, char *argv[])
{GtkWidget *window;GtkWidget *vbox;GtkWidget *menubar;GtkWidget *viewmenu;GtkWidget *view;GtkWidget *tog_stat;GtkWidget *statusbar;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);gtk_window_set_title(GTK_WINDOW(window), "view statusbar");vbox = gtk_vbox_new(FALSE, 0);gtk_container_add(GTK_CONTAINER(window), vbox);menubar = gtk_menu_bar_new();viewmenu = gtk_menu_new();view = gtk_menu_item_new_with_label("View");tog_stat = gtk_check_menu_item_new_with_label("View Statusbar");gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tog_stat), TRUE);gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), viewmenu);gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), tog_stat);gtk_menu_shell_append(GTK_MENU_SHELL(menubar), view);gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3);statusbar = gtk_statusbar_new();gtk_box_pack_end(GTK_BOX(vbox), statusbar, FALSE, TRUE, 1);g_signal_connect_swapped(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);g_signal_connect(G_OBJECT(tog_stat), "activate", G_CALLBACK(toggle_statusbar), statusbar);gtk_widget_show_all(window);gtk_main();return 0;
}

在我们的代码示例中,我们展示了如何去制造一个带有选择框的菜单选项。具体的功能是:如果选择框被选中则“状态栏”就会显示出来,反之则不会显示。

tog_stat = gtk_check_menu_item_new_with_label("View Statusbar");

函数gtk_check_menu_item_new_with_label() 可以生成一个新的带有选择框的菜单选项。

if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {gtk_widget_show(statusbar);
} else {gtk_widget_hide(statusbar);
}

如果选择框被选中则“状态栏”就会显示出来,反之则不会显示。

Figure: Check menu item

工具栏(A toolbar)

菜单栏为我们编程时实现某种功能提供了方便与快捷。在接下来的章节中,我们将为你展示一种在特定情况下可以更加便捷的的方法——制造一个“工具栏。”

#include <gtk/gtk.h>int main( int argc, char *argv[])
{GtkWidget *window;GtkWidget *vbox;GtkWidget *toolbar;GtkToolItem *new;GtkToolItem *open;GtkToolItem *save;GtkToolItem *sep;GtkToolItem *exit;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);gtk_window_set_title(GTK_WINDOW(window), "toolbar");vbox = gtk_vbox_new(FALSE, 0);gtk_container_add(GTK_CONTAINER(window), vbox);toolbar = gtk_toolbar_new();gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);new = gtk_tool_button_new_from_stock(GTK_STOCK_NEW);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new, -1);open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), open, -1);save = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), save, -1);sep = gtk_separator_tool_item_new();gtk_toolbar_insert(GTK_TOOLBAR(toolbar), sep, -1); exit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), exit, -1);gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5);g_signal_connect(G_OBJECT(exit), "clicked", G_CALLBACK(gtk_main_quit), NULL);g_signal_connect_swapped(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);gtk_widget_show_all(window);gtk_main();return 0;
}

以上的代码中,我们制作了一个简单的工具栏实现。

toolbar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS)

从上面的两行代码中你应该可以看出来,我们生成了一个“崭新”的工具栏:)。我们还特地使他们都用图片来显示,没有包含文字。

new = gtk_tool_button_new_from_stock(GTK_STOCK_NEW);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), new, -1);

从 stock中我们生成了一个新的工具栏按钮。要想把工具栏按钮插入到工具栏中,很简单!只需要调用函数 gtk_toolbar_insert() 就可以搞定。

sep = gtk_separator_tool_item_new();
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), sep, -1);

上面的代码,我们生成了一个分割线把工具栏按钮们分开(只是逻辑上的分组需要)。

Figure: Toolbar

功能失效(Undo redo)

在接下来的例子中,我们将展示一个神奇的功能:使工具栏中的一个按钮功能失效(让他变成阴影)。这在GUI设计中是一个常见的技巧。 举个例子:当我们把一片文章单击保存后,那个保存按钮就会变成阴影状,也就是功能失效了。就是来提示你:保存功能已经执行过了,不需要再执行保存功能了。

#include <gtk/gtk.h>
#include <string.h>void undo_redo(GtkWidget *widget,  gpointer item)
{static int count = 2;const char *name = gtk_widget_get_name(widget);if ( strcmp(name, "undo") ) {count++;} else {count--;}if (count < 0) {gtk_widget_set_sensitive(widget, FALSE);gtk_widget_set_sensitive(item, TRUE);} if (count > 5) {gtk_widget_set_sensitive(widget, FALSE);gtk_widget_set_sensitive(item, TRUE);}
}int main( int argc, char *argv[])
{GtkWidget *window;GtkWidget *vbox;GtkWidget *toolbar;GtkToolItem *undo;GtkToolItem *redo;GtkToolItem *sep;GtkToolItem *exit;gtk_init(&argc, &argv);window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);gtk_window_set_default_size(GTK_WINDOW(window), 250, 200);gtk_window_set_title(GTK_WINDOW(window), "undoredo");vbox = gtk_vbox_new(FALSE, 0);gtk_container_add(GTK_CONTAINER(window), vbox);toolbar = gtk_toolbar_new();gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);undo = gtk_tool_button_new_from_stock(GTK_STOCK_UNDO);gtk_widget_set_name(GTK_WIDGET(undo), "undo");gtk_toolbar_insert(GTK_TOOLBAR(toolbar), undo, -1);redo = gtk_tool_button_new_from_stock(GTK_STOCK_REDO);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), redo, -1);sep = gtk_separator_tool_item_new();gtk_toolbar_insert(GTK_TOOLBAR(toolbar), sep, -1); exit = gtk_tool_button_new_from_stock(GTK_STOCK_QUIT);gtk_toolbar_insert(GTK_TOOLBAR(toolbar), exit, -1);gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5);g_signal_connect(G_OBJECT(undo), "clicked", G_CALLBACK(undo_redo), redo);g_signal_connect(G_OBJECT(redo), "clicked", G_CALLBACK(undo_redo), undo);g_signal_connect(G_OBJECT(exit), "clicked", G_CALLBACK(gtk_main_quit), NULL);g_signal_connect_swapped(G_OBJECT(window), "destroy",G_CALLBACK(gtk_main_quit), NULL);gtk_widget_show_all(window);gtk_main();return 0;
}

我们的例子中用到了 GTK+ stock 来实现是 “功能有效”还是“功能失效”。当你单击几下 按钮后,那个按钮就会变成阴影状,也就是说他从“功能有效”变成了“功能失效”。

if (count < 0) {gtk_widget_set_sensitive(widget, FALSE);gtk_widget_set_sensitive(item, TRUE);
} if (count > 5) {gtk_widget_set_sensitive(widget, FALSE);gtk_widget_set_sensitive(item, TRUE);
}

gtk_widget_set_sensitive() 是被用来告诉计算机是否要击活一个工具栏按钮。

Figure: Undo redo

转载于:https://my.oschina.net/xchsp/blog/384028

“菜单”(menubar)和“工具栏”(toolbars)相关推荐

  1. Menu菜单,MenuBar菜单栏,MenuItem菜单项

    Menu菜单,MenuBar菜单栏,MenuItem菜单项 菜单栏: public class MenuDemo { public static void main(String args[]) { ...

  2. QT打印窗口、退出、设置字体及颜色、设置时间、控件实现系统函数、添加资源文件(菜单图片)、工具栏添加图片

    打印窗口 #include <QPrintDialog> 退出 QObject::connect(ui->exitAction, SIGNAL(triggerd()), this, ...

  3. Qt用代码实现菜单栏(MenuBar)和工具栏(ToolBar)

    新建Qt项目,选择Qt Widgets Application,填入项目名称"ImageView",点击完成. 在Qt Designer里会生成如图所示的几个文件: 此时我们右键删 ...

  4. qt中添加资源文件以及添加菜单图标、工具栏中菜单的快捷方式、窗口以及对话框的icon

    1.file--new-QT resource file,就会在工程中添加一个资源文件,然后单击Add下拉框,选择Add prefix,可以将生成的/new/prefix的后缀改为其他的名字,如fil ...

  5. Qt 用代码实现菜单栏(MenuBar)和工具栏(ToolBar)

    新建Qt项目,选择Qt Widgets Application,填入项目名称"ImageView",点击完成. 在Qt Designer里会生成如图所示的几个文件: 此时我们右键删 ...

  6. 第十二章、Designer中的menu菜单、toolBar工具栏和Action动作

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 Qt Designer中的部件栏并没有菜单.toolBar以及Action相关的部件,仅在 ...

  7. Qt QML 菜单/目录/工具栏的全面攻略(TabBar、MenuBar、ToolBar、Button定制、Listview、Repeater)

    Qt QML 菜单/目录/工具栏的全面攻略 1. TabBar的工具栏/目录 1.1 演示 1.2 关键控件 1.3 源码 2 MenuBar 菜单 2.1 演示 2.2 关键控件 2.3 源码 3 ...

  8. 在PyQt中构建 Python 菜单栏、菜单和工具栏

    摘要:菜单.工具栏和状态栏是大多数GUI 应用程序的常见且重要的图形组件.您可以使用它们为您的用户提供一种快速访问应用程序选项和功能的方法. 本文分享自华为云社区<Python 和 PyQt:创 ...

  9. 二级菜单打开一个时其他关闭_简介——菜单和工具栏

    1.1 ChemDraw用户界面(ChemDraw User Interface) 默认情况下,用户界面由常用工具栏,主菜单和文档状态栏组成.用户界面如下图所示: ChemDraw用户界面 1.2 菜 ...

  10. python从excel读彩票数据统计分析,用matplotlib.pyplot做可视图在程序窗口显示,并可动态切换Canvas的可视图,窗口里还添加了菜单和Button按钮工具栏,按钮换图

    # -*- coding: utf-8 -*- """ Created on Tue May 14 18:58:50 2019 把图片保存成了文件,供gui窗口读取,取消 ...

最新文章

  1. python【蓝桥杯vip练习题库】ALGO-142 P1103(复数运算)
  2. 烂泥:学习tomcat之通过shell批量管理多个tomcat
  3. Androidx ViewPager+Fragment 懒加载
  4. PyTorch基础-使用LSTM神经网络实现手写数据集识别-08
  5. 依赖注入:一个Mini版的依赖注入框架
  6. deferred Transports Protocols 简单介绍
  7. ajax兼容低版本浏览器
  8. python kivy canvas_python – Kivy:使用canvas为动画设置动画的正确方法是什么?
  9. Myeclipse学习总结(15)——Eclipse/MyEclipse中Maven项目常见问题解决汇总
  10. 简单的php文件_简单的php文件上传(实例)
  11. TypeError: Object of type ‘TrackedArray‘ is not JSON serializable
  12. joomla 1.5 笔记
  13. 可穿戴设备的发展与挑战
  14. 对JSP内置对象的部分总结
  15. IMX8MQ MEK 开发板安卓 8.1-2.0.0 环境搭建过程记录
  16. 如何点亮QQ邮箱图标 - 龙 炫家族特权
  17. 阿里云因发现Log4j2 核弹级漏洞,未及时上报,被工信部处罚。。
  18. 凹凸技术揭秘 · Tide 研发平台 · 布局研发新基建
  19. html与css入门经典doc,HTML+CSS入门 flying-saucer如何利用HTML来生成PDF文件
  20. alitum designer 快速制作元器件封装

热门文章

  1. webSocket 实现消息推送、心跳、已读消息、加载更多等功能
  2. 微信小程序开发收藏经验(一)
  3. CTF题记——再战GK、BUU
  4. 【Python | X先生】从00-90后的微信昵称,发现如下规律。。。
  5. 美国秘密命令谷歌、微软和雅虎交出搜索指定关键词的人员信息
  6. java毕业设计家居体验平台的设计与实现Mybatis+系统+数据库+调试部署
  7. UVa 1595-对称轴
  8. windows下删除EISA配置分区
  9. oracle怎么启memory,修改memory内存参数,导致数据库启不来
  10. 浏览器主页被劫持的解决办法、浏览器劫持是什么意思