python gui button回调函数运行完成后弹出窗口_嵌入式设备GUI开发之GTK+入门(一)...
小伙伴们大家好,最近鑫哥带领大家做了很多的C语言的小项目,那有些小伙伴说我们可以用python做图形界面,我们可以使用C语言做吗?
我的回答是当然没问题嘻嘻,接下来鑫哥就带大家一起去看看如何进行GTK+的入门。(最下方有彩蛋嘻嘻)
第一章Gtk+入门
1.1引言:
我们从今天开始就学习一下Gtk图形界面的开发,也就是GUI开发,在这个阶段我们采用的是gtk+这个库,只所以采用这个库,是因为这个库给我们提供的接口是C语言的,我们正好上个阶段学过了C语言。我们通过这个库,强化一下大家对C语言的掌握。
我们今天学习一下gtk+的入门,虽然是入门,但是今天是非常重要的,只要今天的知识掌握了,后面两天的知识理解起来就比较容易了。
在入门这一章中我们讲一下概述和开启GTK+之旅
1.2概述
1.2.1 什么是GUI
GUI含义:(Graphics User Interface)
图形用户界面,是计算机与使用者之间的对话接口,是计算机重要的组成部分,比如说咱们使用电脑或手机看到的Windows的桌面或wps软件显示的窗口界面等都是GUI,都是图形界面开发出来的图形界面的软件。
GUI组成
桌面、视窗、菜单、按钮、图标等等
GUI特点
可以使操作更加简单,更加快捷、更加人性化。八十岁的老奶奶也会使用智能手机
早期的操作系统比如DOS,属于CUI(Command line User Interface)
命令行模式的人机接口。
CUI显示本机网络信息 cmd输入命令:ipconfig
GUI显示网络信息的方法
1.2.2 什么是GTK+
GTK+是一套在GIMP的基础上发展而来的高级的、可伸缩的现代化、跨平台图形工具包,它可以很方便地制作图形交互界面( GUI )。
GTK+特点:
稳定、跨平台、多种语言绑定、接口丰富、与时俱进、算法丰富、移动嵌入式应用广泛
http://www.gtk.org/features.php
如何学习GTK+
1、手册-《GTK参考文档》
包括控件的简介、相关详细函数的介绍、个别例程的源码及讲解等
2、教程-《foundations of gtk+ development》《GTK+2.0编程范例》《GTK+2.0》
阅读书籍,随数进行编程练习
3、社区-http://www.gtkforums.com http://gtk.awaysoft.com
4、见参考资料
1.3开启GTK+之旅
1.3.1环境搭建
1、参考《01.配置及编译说明(linux).txt》进行linux编译环境的搭建
2、参考《02.配置及编译说明(A53).txt》进行A53编译环境的搭建
1.3.2空白窗口
创建一个空白窗口 例first_window.c
效果:
代码:
注:编译和执行基本的GTK+程序(linux)
直接使用gcc命令或者编写Makefile来编译
编译的时候需要加上:`pkg-config --cflags --libs gtk+-2.0` ( ` 为数字1键前面那个字符 )
如: gcc demo.c -o demo `pkg-config --cflags --libs gtk+-2.0`
解释:pkg-config --cflags --libs gtk+-2.0
自动获得预处理参数,如宏定义,头文件的位置
自动获得链接参数,如库及依赖的其它库的位置,文件名及其它一些连接参数。
GTK程序的基本框架
GTK+程序的基本框架分析
头文件〈gtk/gtk.h> 包括了GTK+中所有的控件、变量、函数和结构的声明。
gtk_init():这个函数必须在控件定义之前使用,参数由命令行中解析出来并且送到该程序中。
主要作用是设立GTK+运行环境,自动完成一些必要的初始化工作。
创建GtkWidget窗口控件,并且让它显示出来。
gtk_main():程序运行停在这里等待事件(如键盘事件或鼠标事件)的发生,等待用户来操作窗口。这个函数在所有的GTK+程序都要调用。
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget是GTK+控件类型,GtkWidget * 能指向任何控件的指针类型。
gtk_window_new()创建一个窗口并返回这个窗口的控件指针。
GTK_WINDOW_TOPLEVEL指明窗口的类型为最上层的主窗口,它最常用。
gtk_widget_show(window);用来显示上一步创建的窗口控件。
窗口的详细设置
窗口的创建
GtkWidget *gtk_window_new(GtkWindowType type);
GtkWindowType是一个枚举,有两种情况:
GTK_WINDOW_TOPLEVEL:有边框
GTK_WINDOW_POPUP: 没边框
标题的设置
void gtk_window_set_title(GtkWindow *window, const gchar *title);
窗口最小大小的设置
void gtk_widget_set_size_request(GtkWidget *widget,gint width,gint height);
窗口伸缩设置( FALSE为不可伸缩 )TRUE
void gtk_window_set_resizable(GtkWindow *window, gboolean resizable);
显示或隐藏所有控件
void gtk_widget_show_all(GtkWidget *widget);
void gtk_widget_hide_all(GtkWidget *widget);
窗口在显示器位置的设置
void gtk_window_set_position(
GtkWindow *window,
GtkWindowPosition position);
position常用有4种情况:
GTK_WIN_POS_NONE: 不固定
GTK_WIN_POS_CENTER: 居中
GTK_WIN_POS_MOUSE: 出现在鼠标位置
GTK_WIN_POS_CENTER_ALWAYS: 窗口总是居中
例1:Window.c
效果:
代码:
#include <gtk/gtk.h> // 头文件int main( int argc,char *argv[] )
{gtk_init(&argc, &argv); // 初始化// 创建顶层窗口GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);// 设置窗口的标题gtk_window_set_title(GTK_WINDOW(window), "Window");// 设置窗口在显示器中的位置为居中gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);// 设置窗口的最小大小gtk_widget_set_size_request(window, 400, 300);// 固定窗口的大小gtk_window_set_resizable(GTK_WINDOW(window), FALSE); // "destroy" 和 gtk_main_quit 连接g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);gtk_widget_show_all(window); // 显示窗口全部控件//gtk_widget_hide_all(window); // 隐藏窗口gtk_main(); // 主事件循环return 0;
}
1.3.3进阶体验---带按钮的窗口
控件的介绍
1、控件是对数据和方法的封装。控件有自己的属性和方法。属性是指控件的特征。方法是指控件的一些简单而可见的功能。
2、控件的分类:容器控件,非容器控件。
容器控件:它可以容纳别的控件。容器控件分为两类,一类只能容纳一个控件,如窗口,按钮;另一类能容纳多个控件,如布局控件。
非容器控件:它不可以容纳别的控件,如标签、行编辑。
带按钮的窗口
创建一个带内容的按钮
GtkWidget *gtk_button_new_with_label(const gchar *label );
获得按钮上面的文本内容
const gchar *gtk_button_get_label(GtkButton *button );
把控件添加到窗口容器里
void gtk_container_add(GtkContainer*container,GtkWidget*widget);
container:容纳控件的容器;widget:要添加的控件
例1:window_with_button.c 带按钮的窗口
效果:
代码:
#include <gtk/gtk.h> // 头文件int main( int argc,char *argv[] )
{gtk_init(&argc, &argv); // 初始化GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建顶层窗口// 设置窗口边框的宽度(窗口里的控件与窗口边框间隔为15)gtk_container_set_border_width(GTK_CONTAINER(window), 15);// 创建按钮,文本信息为"Hello GTK+"GtkWidget *button = gtk_button_new_with_label("Hello GTK+");const char *str = gtk_button_get_label( GTK_BUTTON(button) ); // 获得按钮的内容printf("str = %sn", str);// 把按钮放入窗口(窗口也是一种容器)gtk_container_add(GTK_CONTAINER(window), button);// 显示控件有两种方法:逐个显示,全部显示// gtk_widget_show(button);// gtk_widget_show(window);gtk_widget_show_all(window); // 显示窗口全部控件gtk_main(); // 主事件循环return 0;
}
控件类型的转换
使用控件接口时,一定要注意参数类型是否匹配
const char *str = gtk_button_get_label( GTK_BUTTON(button) );
#define GTK_BUTTON(x) (GtkButton *)(x)
在参考文档里查看控件之间的继承关系
1.3.4动起来---信号与回调函数机制
信号与回调函数机制
GTK+采用了信号与回调函数来处理窗口外部传来的事件、消息或信号。当信号发生时,程序自动调用为信号连接的回调函数。
窗口关闭时触发的常用信号:destroy, delete-event
操作按钮触发的常用信号:clicked, pressed,released
信号与回调函数的连接
gulong g_signal_connect(
gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer data );
instance: 信号的发出者
detailed_signal: 要连接信号的名称
c_handler: 回调函数的名称,需要用G_CALLBACK()进行转换
data: 传递给回调函数的参数
回调函数的定义
信号连接函数的写法:
g_signal_connect(button, "pressed",
G_CALLBACK(callback), NULL);
回调函数的定义(参考“参考文档”)
void callback( GtkButton *button,
gpointer user_data );
button: 信号的发出者
user_data:传给回调函数的数据
例1:signal.c
#include <gtk/gtk.h> // 头文件// 按钮按下的处理函数, gpointer 相当于 void *
void deal_pressed(GtkButton *button, gpointer user_data)
{// 获得按钮的文本信息const gchar *text = gtk_button_get_label( button );// g_print() 相当于C语言的 printf(), gchar相当于charg_print("button_text = %s; user_data = %sn", text, (gchar *)user_data);
}int main( int argc,char *argv[] )
{gtk_init(&argc, &argv); // 初始化GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建顶层窗口// 设置窗口边框的宽度(窗口里的控件与窗口边框间隔为15)gtk_container_set_border_width(GTK_CONTAINER(window), 15);/* 当窗口关闭时,窗口会触发destroy信号,* 自动调用gtk_main_quit()结束程序运行。*/g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);GtkWidget *button = gtk_button_new_with_label("Hello GTK+"); // 创建按钮gtk_container_add(GTK_CONTAINER(window), button); // 把按钮放入窗口(窗口也是一种容器)/* 按钮按下(pressed)后会自动调用deal_pressed()* "is pressed"是传给deal_pressed()的数据*/g_signal_connect(button, "pressed", G_CALLBACK(deal_pressed), "is pressed");gtk_widget_show_all(window); // 显示窗口全部控件gtk_main(); // 主事件循环return 0;
}
1.3.5常用布局
什么是布局
设定控件在整个窗口中的位置和尺寸
常用的布局方式
水平布局 GtkHBox
垂直布局 GtkVBox
表格布局 GtkTable
固定布局 GtkFixed
1.3.5.1水平布局
使用的函数
创建水平布局容器
GtkWidget*gtk_hbox_new(gboolean homogeneous, gint spacing);
homogeneous:容器内控件是否均衡排放(大小一致) TRUE表示均匀
spacing: 控件之间的间隔
添加控件到布局容器中
gtk_container_add(GtkContainer*container, GtkWidget *widget );
GUI的描述:
我们想要做一个窗口,在窗口中有一个水平布局,在布局中放入三个按钮
中文代码编辑流程框架:
1.包含头文件
2.主函数(去掉const)
2.1gtk环境初始化
2.2新建一个窗口
2.3设置窗口属性
2.4创建一个水平布局
2.5将水平布局放入窗口中
2.6创建按钮-放入布局中
2.7信号连接
2.8显示窗口中的所有控件
2.9主事件循环
return 0;
编写代码:
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{gtk_init(&argc,&argv);GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);GtkWidget* hbox = gtk_hbox_new(TRUE,20);gtk_container_add(GTK_CONTAINER(window),hbox);GtkWidget* button1 = gtk_button_new_with_label("button1");gtk_container_add(GTK_CONTAINER(hbox),button1);GtkWidget* button2 = gtk_button_new_with_label("button2");gtk_container_add(GTK_CONTAINER(hbox),button2);GtkWidget* button3 = gtk_button_new_with_label("button3");gtk_container_add(GTK_CONTAINER(hbox),button3);g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);gtk_widget_show_all(window);gtk_main();return 0;
}
垂直布局 GtkVBox
使用的新接口函数
创建垂直布局容器
GtkWidget*gtk_box_new(gboolean homogeneous, gint spacing);
homogeneous:容器内控件是否均衡排放(大小一致) TRUE表示均匀
spacing: 控件之间的间隔
添加控件到布局容器中
gtk_container_add(GtkContainer*container, GtkWidget *widget );
标签的创建
GtkWidget *gtk_label_new(const gchar *str);
设置标签的内容
void gtk_label_set_text(GtkLabel *label, const gchar *str);
获得标签的内容
const gchar *gtk_label_get_label(GtkLabel *label );
GUI的描述:
我们想要做一个窗口,在窗口中有一个垂直布局,在布局中放入三个文本
中文代码编辑流程框架:
1.包含头文件
2.主函数(去掉const)
2.1gtk环境初始化
2.2新建一个窗口
2.3设置窗口属性
2.4创建一个垂直布局
2.5将垂直布局放入窗口中
2.6创建文本-放入布局中
2.7信号连接
2.8显示窗口中的所有控件
2.9主事件循环
return 0;
编写代码:
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{gtk_init(&argc,&argv);GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);GtkWidget* vbox = gtk_vbox_new(TRUE,20);gtk_container_add(GTK_CONTAINER(window),vbox);GtkWidget* label1 = gtk_label_new("label1");gtk_container_add(GTK_CONTAINER(vbox),label1);GtkWidget* label2 = gtk_label_new("label2");gtk_container_add(GTK_CONTAINER(vbox),label2);GtkWidget* label3 = gtk_label_new("label3");gtk_container_add(GTK_CONTAINER(vbox),label3);g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);gtk_widget_show_all(window);gtk_main();return 0;
}
表格布局 GtkTable
使用的新的接口函数:
创建表格布局容器
GtkWidget*gtk_table_new(guint rows,guint columns,gboolean homogeneous );
rows:行数
coumns:列数
homogeneous:容器内表格的大小是否一致
添加控件到布局容器中
void gtk_table_attach_defaults(GtkTable *table,GtkWidget *widget, guintleft_attach,
guint right_attach,
guint top_attach,
guint bottom_attach );
table: 要容纳控件的容器
widget: 被容纳控件
GUI需求:
如上图所示,我想做出一个由两个按钮进行文本控制的界面,当按钮大可爱被按下的时候,文本就变成大可爱,当小可爱被按下的时候,文本就变成小可爱
代码中文框架:
1.包含头文件
2.回调函数的声明
3.主函数(去掉const)
3.1gtk环境初始化
3.2创建一个窗口
3.3创建一个表格布局
3.4将表格布局放入窗口中
3.5创建label 放入表格布局中指定位置
3.6创建两个按钮,分布放入表格的指定位置
3.7信号连接
窗口的关闭信号连接、两个按钮的信号连接
3.8显示所有控件
3.9主事件循环
return 0;
4.回调函数的定义
4.1获取按钮内容
4.2将内容设置到label上
(或者使用直接将获取到的按钮内容设置到label上)
代码的编写:
#include <gtk/gtk.h>
void keai(GtkButton *button,gpointer user_data);
int main(int argc, char *argv[])
{gtk_init(&argc,&argv);GtkWidget*window = gtk_window_new(GTK_WINDOW_TOPLEVEL);GtkWidget* table = gtk_table_new(2,2,TRUE);gtk_container_add(GTK_CONTAINER(window),table);GtkWidget* label = gtk_label_new("");gtk_table_attach_defaults(GTK_TABLE(table),label,0,2,0,1);GtkWidget* button1 = gtk_button_new_with_label("大可爱");gtk_table_attach_defaults(GTK_TABLE(table),button1,0,1,1,2);GtkWidget* button2 = gtk_button_new_with_label("小可爱");gtk_table_attach_defaults(GTK_TABLE(table),button2,1,2,1,2);g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);g_signal_connect(button1,"pressed",G_CALLBACK(keai),label);g_signal_connect(button2,"pressed",G_CALLBACK(keai),label);gtk_widget_show_all(window);gtk_main();return 0;
}
void keai(GtkButton *button,gpointer user_data)
{const char * haha = gtk_button_get_label(button);gtk_label_set_text(GTK_LABEL(user_data),haha);return;
}
固定布局 GtkFixed
需要使用的新接口函数:
创建固定布局容器
GtkWidget *gtk_fixed_new(void);
添加控件到容器中
void gtk_fixed_put( GtkFixed *fixed, GtkWidget *widget,gint x,gint y );
fixed:要容纳控件的容器;widget:被容纳控件
x,y: 控件摆放位置的起点坐标
案例代码:
#include <gtk/gtk.h>
int main(int argc, char *argv[])
{gtk_init(&argc,&argv);GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);GtkWidget* fixed = gtk_fixed_new();gtk_container_add(GTK_CONTAINER(window),fixed);GtkWidget* label = gtk_label_new("123123123");gtk_fixed_put(GTK_FIXED(fixed),label,100,200);g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);gtk_widget_show_all(window);gtk_main();return 0;
}
1.3.6行编辑
1.3.6.1行编辑的创建
GtkWidget *gtk_entry_new(void);
1.3.6.2显示模式(FALSE为密码模式)
void gtk_entry_set_visibility(
GtkEntry *entry,
gboolean visible );
1.3.6.3获得文本内容
const gchar *gtk_entry_get_text(
GtkEntry *entry );
1.3.6.4设置行编辑的内容
void gtk_entry_set_text(GtkEntry *entry,
const gchar *text);
1.3.6.5常用信号:
activate,按回车键触发
例:entry.c 行编辑
效果:
#include <gtk/gtk.h> // 按Enter,获取行编辑的内容
void enter_callback( GtkWidget *widget, gpointer entry )
{ const gchar *entry_text; // 获得文本内容entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); printf("Entry contents: %sn", entry_text);
}int main( int argc, char *argv[] )
{ gtk_init (&argc, &argv); // 初始化GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建窗口gtk_window_set_title(GTK_WINDOW(window), "GTK Entry"); // 设置标题g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); GtkWidget *vbox = gtk_vbox_new(TRUE, 5); // 垂直布局,控件均衡摆放,控件间距为0gtk_container_add(GTK_CONTAINER(window), vbox); // 容器放入窗口GtkWidget *entry = gtk_entry_new(); // 创建行编辑 gtk_container_add(GTK_CONTAINER(vbox), entry); // 加入垂直布局里gtk_entry_set_max_length(GTK_ENTRY(entry), 100); // 设置行编辑显示最大字符的长度gtk_entry_set_text(GTK_ENTRY(entry), "hello word"); // 设置内容gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); // 密码模式/* 如果我们想在用户输入文本时进行响应,可以为activate设置回调函数。* 当用户在文本输入构件内部按回车键时引发Activate信号;*/g_signal_connect(entry, "activate", G_CALLBACK(enter_callback), entry);GtkWidget *hbox = gtk_hbox_new(TRUE, 0); // 水平布局容器gtk_container_add(GTK_CONTAINER(vbox), hbox); // 水平布局容器加入垂直布局容器里// "button 1"GtkWidget *button1 = gtk_button_new_with_label("button 1"); gtk_container_add(GTK_CONTAINER(hbox), button1); // 按钮1添加到水平布局容器里// "button 2"GtkWidget *button2 = gtk_button_new_with_label("button 2"); gtk_container_add(GTK_CONTAINER(hbox), button2); // 按钮2添加到水平布局容器里// close buttonGtkWidget *button_close = gtk_button_new_with_label("close"); g_signal_connect(button_close, "clicked", G_CALLBACK (gtk_main_quit), NULL); gtk_container_add(GTK_CONTAINER(vbox), button_close); // 关闭按钮添加到垂直布局容器里gtk_widget_show_all(window); // 显示窗口所有控件gtk_main(); // 主事件循环return 0;
}
第二章:常用控件
2.1按钮(GtkButton)
2.1.1带图标按钮的创建
void gtk_button_set_image(GtkButton *button, GtkWidget *image);
image:通过gtk_image_new_from_file()来创建,参数为图片的路径
2.1.2设置按钮透明背景色
void gtk_button_set_relief(
GtkButton *button, GtkReliefStyle newstyle);
newstyle: GTK_RELIEF_NONE为透明
例:button.c
> // 头文件// 回调函数
void callback(GtkButton *button, gpointer data)
{const char *str = gtk_button_get_label( button ); // 获得按钮的文本内容printf("str = %sn", str);GtkWidget *image = gtk_image_new_from_file("2.jpg"); // 图像控件gtk_button_set_image(GTK_BUTTON(button), image);
}int main(int argc, char *argv[])
{ gtk_init(&argc, &argv); // 初始化GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建窗口gtk_window_set_title(GTK_WINDOW(window), "button");// 设置标题 g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_container_set_border_width(GTK_CONTAINER(window), 10); // 设置窗口边框的宽度gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); // 窗口居中GtkWidget *hbox = gtk_hbox_new(TRUE, 10); // 水平布局容器gtk_container_add(GTK_CONTAINER(window), hbox); // 把横向盒状容器放入窗口// 普通按钮GtkWidget *normal_button = gtk_button_new_with_label("normal button");gtk_button_set_label(GTK_BUTTON(normal_button), "change"); // 设置按钮的文本内容g_signal_connect(normal_button, "pressed", G_CALLBACK(callback), NULL);gtk_container_add(GTK_CONTAINER(hbox), normal_button); // 把按钮放入横向容器里// 带图标按钮GtkWidget *button = gtk_button_new(); // 先创建空按钮GtkWidget *image = gtk_image_new_from_file("1.png"); // 图像控件gtk_button_set_image(GTK_BUTTON(button), image);gtk_container_add(GTK_CONTAINER(hbox), button); // 把按钮放入横向容器里gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); // 按钮背景色透明// 按钮使能设置,默认为使能TRUE,非使能FALSE//gtk_widget_set_sensitive(button, FALSE);gtk_widget_show_all(window); // 显示窗口控件gtk_main(); // 主事件循环return 0;
}
2.2图片资源对象(GdkPixbuf)
2.2.1图片资源对象的创建
GdkPixbuf *gdk_pixbuf_new_from_file(
const gchar *filename, GError **error);
filename:图片路径;error: 储存错误的指针
2.2.2设置图片的大小
GdkPixbuf *gdk_pixbuf_scale_simple(
const GdkPixbuf *src, int dest_width,
int dest_height, GdkInterpType interp_type);
interp_type:是一个枚举变量,标志图片的加载速度和质量,常用GDK_INTERP_BILINEAR
2.2.3释放资源
void g_object_unref(GtkObject *object);
2.3图片控件(GtkImage)
2.3.1通过图片资源对象创建图片控件
GtkWidget *gtk_image_new_from_pixbuf(
GdkPixbuf *pixbuf );
2.3.2图片控件重新设置一张图片(pixbuf)
void gtk_image_set_froma_pixbuf(
GtkImage *image, GdkPixbuf *pixbuf );
2.3.3清除控件里的图像数据
void gtk_image_clear(GtkImage *image);
例:demo.c
#include <gtk/gtk.h>typedef struct _Window
{GtkWidget *main_window;GtkWidget *table;GtkWidget *image;GtkWidget *button_previous;GtkWidget *button_next;
}WINDOW;// 给创建好的image重新设计一张图片
void load_image(GtkWidget *image, const char *file_path, const int w, const int h )
{gtk_image_clear( GTK_IMAGE(image) ); // 清除图像GdkPixbuf *src_pixbuf = gdk_pixbuf_new_from_file(file_path, NULL); // 创建图片资源GdkPixbuf *dest_pixbuf = gdk_pixbuf_scale_simple(src_pixbuf, w, h, GDK_INTERP_BILINEAR); // 指定大小gtk_image_set_from_pixbuf(GTK_IMAGE(image), dest_pixbuf); // 图片控件重新设置一张图片(pixbuf)g_object_unref(src_pixbuf); // 释放资源g_object_unref(dest_pixbuf); // 释放资源
}// 根据图片路径创建一个新按钮,同时指定图片大小
GtkWidget *create_button_from_file(const char *file_path, const int w, const int h)
{GtkWidget *temp_image = gtk_image_new_from_pixbuf(NULL);load_image(temp_image, file_path, w, h);GtkWidget *button = gtk_button_new(); // 先创建空按钮gtk_button_set_image(GTK_BUTTON(button), temp_image); // 给按钮设置图标gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); // 按钮背景色透明return button;
}// 按钮的回调函数
void deal_switch_image(GtkWidget *button, gpointer data)
{WINDOW *p_temp = (WINDOW *)data;if(button == p_temp->button_previous){ // 上一张printf("p_temp->button_previousn");}else if(button == p_temp->button_next ){ // 下一张printf("p_temp->button_nextn");}
}void window_demo(gpointer data)
{WINDOW *p_temp = (WINDOW *)data;// 主窗口p_temp->main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建主窗口gtk_window_set_title(GTK_WINDOW(p_temp->main_window), "image"); // 设置窗口标题gtk_window_set_position(GTK_WINDOW(p_temp->main_window), GTK_WIN_POS_CENTER); // 设置窗口在显示器中的位置为居中gtk_widget_set_size_request(p_temp->main_window, 800, 480); // 设置窗口的最小大小gtk_window_set_resizable(GTK_WINDOW(p_temp->main_window), FALSE); // 固定窗口的大小g_signal_connect(p_temp->main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL); // 表格布局p_temp->table = gtk_table_new(7, 7, TRUE); // 表格布局容器gtk_container_add(GTK_CONTAINER(p_temp->main_window), p_temp->table); // 容器加入窗口// 图片控件p_temp->image = gtk_image_new_from_pixbuf(NULL); // 创建图片控件load_image(p_temp->image, "./image/1.jpg", 500, 450);gtk_table_attach_defaults(GTK_TABLE(p_temp->table), p_temp->image, 1, 6, 1, 6); // 把图片控件加入布局// 按钮p_temp->button_previous = create_button_from_file("./image/previous.bmp", 80, 80);gtk_table_attach_defaults(GTK_TABLE(p_temp->table), p_temp->button_previous, 1, 2, 6, 7);g_signal_connect(p_temp->button_previous, "clicked", G_CALLBACK(deal_switch_image), p_temp);p_temp->button_next = create_button_from_file("./image/next.bmp", 80, 80);gtk_table_attach_defaults(GTK_TABLE(p_temp->table), p_temp->button_next, 5, 6, 6, 7);g_signal_connect(p_temp->button_next, "clicked", G_CALLBACK(deal_switch_image), p_temp);gtk_widget_show_all(p_temp->main_window);}int main(int argc, char *argv[])
{gtk_init(&argc, &argv); // 初始化WINDOW window;window_demo(&window);gtk_main(); // 主事件循环return 0;
}
2.4进度条(GtkProgressBar)
2.4.1进度条的创建
GtkWidget *gtk_progress_bar_new(void);
2.4.2设置进度条显示的百分比
void gtk_progress_bar_set_fraction(
GtkProgressBar *pbar, gdouble fraction);
fraction:0.0到1.0
2.4.3设置滑槽上的文本显示
void gtk_progress_bar_set_text(
GtkProgressBar *pbar, gchar *text);
2.4.4设置进度条的移动方向
void gtk_progress_bar_set_orientation(
GtkProgressBar *pbar, GtkProgressBarOrientation orientation);
GTK_PROGRESS_LEFT_TO_RIGHT:从左向右
GTK_PROGRESS_RIGHT_TO_LEFT:从右向左
GTK_PROGRESS_BOTTOM_TO_TOP:从下向上
GTK_PROGRESS_TOP_TO_BOTTOM:从上向下
例:progress_bar.c
#include <gtk/gtk.h>
#include <string.h>// 回调函数,切换进度条的移动方向
void toggle_orientation(GtkWidget *widget, gpointer data)
{ // gtk_progress_bar_get_orientation: 获得进度条当前移动的方向switch( gtk_progress_bar_get_orientation( GTK_PROGRESS_BAR(data) ) ){ case GTK_PROGRESS_LEFT_TO_RIGHT: gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(data), GTK_PROGRESS_RIGHT_TO_LEFT); break; case GTK_PROGRESS_RIGHT_TO_LEFT: gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(data), GTK_PROGRESS_LEFT_TO_RIGHT); break; default: // 什么也不做 break;}
} // 更新进度条,这样就能够看到进度条的移动
void callback(GtkWidget *widget, gpointer data)
{// 在原来值基础上增加 0.05gdouble new_val = gtk_progress_bar_get_fraction( GTK_PROGRESS_BAR(data) ) + 0.05; if(new_val > 1.0){ // 越界处理new_val = 0.0; }// 设置进度条的新值 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data), new_val);
}int main(int argc, char *argv[])
{gtk_init(&argc, &argv); // 初始化GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // 创建主窗口gtk_window_set_title(GTK_WINDOW(window), "GtkProgressBar"); // 设置窗口标题gtk_container_set_border_width(GTK_CONTAINER(window), 10); // 设置边框宽度// 设置窗口在显示器中的位置为居中gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);// 设置窗口的最小大小gtk_widget_set_size_request(window, 300, 200);// 窗口关联 destroy 信号 到 gtk_main_quitg_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);GtkWidget *vbox = gtk_vbox_new(FALSE, 5); // 垂直布局容器gtk_container_add(GTK_CONTAINER(window), vbox); // 容器加入窗口// 创建一个进度条GtkWidget *progress = gtk_progress_bar_new();gtk_container_add(GTK_CONTAINER(vbox), progress); // 加入垂直布局容器// 设置进度条显示的百分比:50%gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 0.5 ); // 设置在进度条的滑槽上的文本显示 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "some text");// 添加一个按钮,切换移动方向 GtkWidget *button_orientation = gtk_button_new_with_label("Right to Left"); g_signal_connect(button_orientation, "clicked", G_CALLBACK(toggle_orientation), progress); // connectgtk_container_add(GTK_CONTAINER(vbox), button_orientation); // 加入垂直布局容器// 增加进度条进度按钮GtkWidget *button = gtk_button_new_with_label("add");g_signal_connect(button, "clicked", G_CALLBACK(callback), progress); // connectgtk_container_add(GTK_CONTAINER(vbox), button); // 加入垂直布局容器gtk_widget_show_all(window);gtk_main(); // 主事件循环return 0;
}
2.5滚动窗口(GtkScrolledWindow)
2.5.1滚动窗口的创建
GtkWidget *gtk_scrolled_window_new(
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment );
第一个参数是水平方向的调整对象,第二个参数是垂直方向的调整对象。它们一般都设置为NULL。
2.5.2滚动窗口添加控件
void gtk_scrolled_window_add_with_viewport(
GtkScrolledWindow *scrolled_window, GtkWidget *child );
2.5.3设置滚动条出现的方式(水平或垂直方向)
void gtk_scrolled_window_set_policy(
GtkScrolledWindow *scrolled_window,
GtkPolicyType hscrollbar_policy,
GtkPolicyType vscrollbar_policy );
GTK_POLICY_AUTOMATIC:滚动条根据需要自动出现
GTK_POLICY_ALWAYS: 滚动条总是出现
GTK_POLICY_NEVER: 不需要滚动条
欢迎小伙伴们使用,也可以同时看鑫哥B站中的视频一起学习,加油
ipod6GTK按钮_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com
结尾彩蛋~鑫哥小时候~
python gui button回调函数运行完成后弹出窗口_嵌入式设备GUI开发之GTK+入门(一)...相关推荐
- python弹窗怎么抓取_在Python中,按POST请求并从弹出窗口中抓取数据
我想按"Suche starten"按钮,从这个页面上为一个研究项目刮取结果(基本上它可以不填任何表格-然后打开一个弹出窗口,保存我想要的数据).在https://www.inso ...
- python win10 捕获 弹出窗口_[python爬虫] Selenium高级篇之窗口移动、弹出对话框自登录...
在我们使用Selenium Python制作自动爬虫和网页自动测试的时候,通常会遇到弹出新的窗体或对话框的时候,此时你捕获的窗体已经被打断,从而干扰你的爬虫. 那怎么解决这个问题呢? 本篇文章主要记录 ...
- 避免window.open弹出窗口被阻止,避免IE7限制,在登录成功后弹出窗口屏蔽菜单栏地址栏
放到连接里,然后用JS伪协议打开就好了 < a href = ' javascript:void window.open("x.html","x",&qu ...
- 用计算机弹出黎明的黑暗,STEAM打开黎明杀机启动游戏后弹出计算机丢失msvcp140period;dllperiod; | 手游网游页游攻略大全...
发布时间:2015-12-23 恐怖黎明游戏进不去怎么办 丢失msvcp140.dll错误怎么办.有玩家在进入恐怖黎明游戏的时候出现系统报错,提示msvcp140.dll错误,导致无法进行游戏,下面9 ...
- python 回调函数的使用_如何在python中使用回调函数?
我想知道如何正确使用 Python 2.7回调函数. 我在我的代码中有一些来自Cherrypy auth示例的回调函数. (这些回调会返回一个可以评估为True或False的函数,具体取决于登录的用户 ...
- python selenium 处理弹窗_python 让selenium(webdriver ) 不打开浏览器(弹出窗口)运行(静默模式启动)...
什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...
- python tkinter 弹窗_Python:tkinter-Parent获取弹出窗口的返回值
获取窗口对象的返回值是一个很常见的模型,比如程序弹出一个窗口,读取用户的输入值,这个值可以很容易的保存在弹出的窗口中,但问题在于如何将这个值传递给弹出窗口的parent.这是一个看似很simple的问 ...
- python的窗口处理模块_Python tkinter模块弹出窗口及传值回到主窗口操作详解
本文实例讲述了Python tkinter模块弹出窗口及传值回到主窗口操作.分享给大家供大家参考,具体如下: 有些时候,我们需要使用弹出窗口,对程序的运行参数进行设置.有两种选择 一.标准窗口 如果只 ...
- java在面板中点击按钮后弹出对话框
1 import javax.swing.*; 2 import java.awt.event.*; 3 import java.awt.*; 4 5 public class ShowDIalog ...
最新文章
- 跨域产生的原因和解决方法_ABS注塑制品产生色差的原因及解决方法
- FPGA之道(23)VHDL的signal、variable与constant
- 大数据分析中国冬季重度雾霾的成因(二)
- UIButton中的三个UIEdgeInsets属性
- tomcat安装与项目部署
- C - Insertion Sort Gym - 101955C(2018icpc沈阳/打表找规律)
- spring javafx_带有Spring的JavaFX 2
- 阿里王帅回应“马云被印度法院传唤”:马云太难找,要去HHB酒吧试试
- oracle truncate闪回数据库恢复
- linux下安装apache + subversionSVN_Subversion
- App拉起:h5打开app指定页面
- 负指数分布的性质_负指数分布.ppt
- 数据分析SQL环比增长率、同比增长率
- java 货币格式 转换_Java 转换货币形式
- TANRIC:肿瘤相关lncRNA数据库
- AutoCAD家具设计入门到精通视频教程
- 印象笔记如何分享链接_几步搞懂印象笔记的链接功能
- 盘点国内好用的企业网盘
- python定义一个类savingaccount表示银行账户_创建一个SavingAccount类
- 艺龙私有化,携程与腾讯眉来眼去
热门文章
- GitHub 长期被中国人“霸榜”?看完榜单我呆了...
- 新人入职,上午写了一段代码,下午就被开除了
- 【升级包】jeecg_online 支持主子表列表展示风格模板升级包,简易升级
- JEECG v3.0.beta发布,基于代码生成器的智能开发平台
- seasar一般性配置
- SpringBoot2 整合 Zookeeper组件,管理架构中服务协调
- BeautifulSoup 用法总结
- ThinkPHP/---合并数组后按时间排序
- 推荐两款 GTD 工具
- 1.4. Open Source and License