“菜单”(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”菜单按钮,程序就会退出。
图象菜单, 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();
菜单选项能够被一个水平的分割线隔开。这样的话我们就可以从逻辑上把一些菜单选项给区分开来。
选择(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);
}
如果选择框被选中则“状态栏”就会显示出来,反之则不会显示。
工具栏(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);
上面的代码,我们生成了一个分割线把工具栏按钮们分开(只是逻辑上的分组需要)。
功能失效(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()
是被用来告诉计算机是否要击活一个工具栏按钮。
“菜单”(menubar)和“工具栏”(toolbars)的更多相关文章
- 第15.15节 PyQt(Python+Qt)入门学习:Designer的menu菜单、toolBar工具栏和Action动作详解
老猿Python博文目录 老猿Python博客地址 一.引言 Qt Designer中的部件栏并没有菜单.toolBar以及Action相关的部件,仅在MainWindow类型窗口提供了menu.to ...
- tkinter菜单图标,工具栏
所用的图片: import tkinter as tk from tkinter import messagebox, filedialog, simpledialog, colorchooser f ...
- ligerUI---下拉菜单(menubar)动态显示(从后台获取数据)
写在前面: ligerui的下拉菜单是有点丑的,这也是没有办法的事........这里主要记录下,如何从后台获取数据进行菜单显示. 有两种方式:1.使用json数组来动态添加 2.字符串拼接. 其 ...
- 第十二章、Designer中的menu菜单、toolBar工具栏和Action动作
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 Qt Designer中的部件栏并没有菜单.toolBar以及Action相关的部件,仅在 ...
- 在PyQt中构建 Python 菜单栏、菜单和工具栏
摘要:菜单.工具栏和状态栏是大多数GUI 应用程序的常见且重要的图形组件.您可以使用它们为您的用户提供一种快速访问应用程序选项和功能的方法. 本文分享自华为云社区<Python 和 PyQt:创 ...
- GEF入门实例_总结_03_显示菜单和工具栏
一.前言 本文承接上一节: GEF入门实例_总结_02_新建初始RCP空项目 这一节,我们来给我们的插件加上菜单. 二.基础知识 1.action bar.menubar.coolbar 含义 a ...
- 基于 SailingEase WinForm Framework 开发客户端程序(3:实现菜单/工具栏按钮的解耦及状态控制)
本系列文章将详细阐述客户端应用程序的设计理念,实现方法. 本系列文章以 SailingEase WinForm Framework 为基础进行设计并实现,但其中的设计理念及方法,亦适用于任何类型的客 ...
- wx工具栏,菜单栏,状态栏
#!/usr/bin/env python # -*- coding: utf- -*- import wx import wx.py.images class ToolbarFrame(wx.Fra ...
- 浅谈Excel开发:二 Excel 菜单系统
在开始Excel开发之前,需要把架子搭起来.最直接的那就是Excel里面的菜单了,他向用户直观的展现了我们的插件具有哪些功能.菜单出来之后我们就可以实现里面的事件和功能了.Excel菜单有两种形式,一 ...
- Java基础之处理事件——添加工具栏(Sketcher 7 with File toolbar buttons)
控制台程序. 工具栏在应用程序窗口中通常位于内容面板顶部的菜单栏下,包含直接访问菜单选项的按钮.在Sketcher程序中可以为最常用的菜单项添加工具栏. 工具栏是javax.swing.JToolBa ...
随机推荐
- DB天气app冲刺二阶段第一天
原来找人也是个力气活...好费劲呀..今天的进度有点慢,,确切的说是没有什么进度 因为不会弄了..加上今天一个劲的找同学帮忙写评论.心思没定下来 根本没思路了..明天按照今天的计划继续冲刺..
- ajaxfileupload踩过的坑
首先ajaxfileupload-jQuery.handleError is not a function这个错误,百度之后发现解决办法就是把 handleError: function( s, xh ...
- Begin Andriod -- 安装android开发环境
很久以前学过Andriod,现在已经忘的快没有了,重新捡起来练练,顺带写写博客,感受下写博的乐趣. 第一步:安装java jdk.jre(jdk:开发环境,jre:运行环境). (一)java jdk ...
- 6779. Can you answer these queries VII - SPOJ
Given a tree with N ( N<=100000 ) nodes. Each node has a interger value x_i ( |x_i|<=10000 ). ...
- Java连接redis的使用示例
在多线程下使用Jedis 在不同的线程中使用相同的Jedis实例会发生奇怪的错误.但是创建太多的实现也不好因为这意味着会建立很多sokcet连接,也会导致奇怪的错误发生.单一Jedis实例不是线程安全 ...
- mysql 增加删除用户
mysql 增加用户 (注意:因为MYSQL环境中的命令,所以后面都带一个分号作为命令结束符) 格式:grant select on 数据库.* to 用户名@登录主机 identified by ' ...
- CSS 命名规范及标题供参考与学习
一.CSS 命名规范 XHTML-CSS写作建议 所有的xhtml代码小写 属性的值一定要用双引号("")括起来,且一定要有值 每个标签都要有开始和结束,且要有正确的层次 空元 ...
- hdu 2516 取石子游戏 博弈论
很显然的nim游戏的变形,很好找规律 先手败:2,3,5,8,13…… 其他先手胜.即满足菲波拉数列. 代码如下: #include<iostream> #include<stdio ...
- 【无聊放个模板系列】BZOJ 1597 斜率优化
STL 双向队列DEQUE版本 #include<cstdio> #include<cstdlib> #include<cstring> #include<i ...
- highcharts 折线图
<!doctype html> <html lang="en"> <head> <script type="text/javas ...