小伙伴们大家好,最近鑫哥带领大家做了很多的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按钮_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com

结尾彩蛋~鑫哥小时候~

python gui button回调函数运行完成后弹出窗口_嵌入式设备GUI开发之GTK+入门(一)...相关推荐

  1. python弹窗怎么抓取_在Python中,按POST请求并从弹出窗口中抓取数据

    我想按"Suche starten"按钮,从这个页面上为一个研究项目刮取结果(基本上它可以不填任何表格-然后打开一个弹出窗口,保存我想要的数据).在https://www.inso ...

  2. python win10 捕获 弹出窗口_[python爬虫] Selenium高级篇之窗口移动、弹出对话框自登录...

    在我们使用Selenium Python制作自动爬虫和网页自动测试的时候,通常会遇到弹出新的窗体或对话框的时候,此时你捕获的窗体已经被打断,从而干扰你的爬虫. 那怎么解决这个问题呢? 本篇文章主要记录 ...

  3. 避免window.open弹出窗口被阻止,避免IE7限制,在登录成功后弹出窗口屏蔽菜单栏地址栏

    放到连接里,然后用JS伪协议打开就好了 < a href = ' javascript:void window.open("x.html","x",&qu ...

  4. 用计算机弹出黎明的黑暗,STEAM打开黎明杀机启动游戏后弹出计算机丢失msvcp140period;dllperiod; | 手游网游页游攻略大全...

    发布时间:2015-12-23 恐怖黎明游戏进不去怎么办 丢失msvcp140.dll错误怎么办.有玩家在进入恐怖黎明游戏的时候出现系统报错,提示msvcp140.dll错误,导致无法进行游戏,下面9 ...

  5. python 回调函数的使用_如何在python中使用回调函数?

    我想知道如何正确使用 Python 2.7回调函数. 我在我的代码中有一些来自Cherrypy auth示例的回调函数. (这些回调会返回一个可以评估为True或False的函数,具体取决于登录的用户 ...

  6. python selenium 处理弹窗_python 让selenium(webdriver ) 不打开浏览器(弹出窗口)运行(静默模式启动)...

    什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...

  7. python tkinter 弹窗_Python:tkinter-Parent获取弹出窗口的返回值

    获取窗口对象的返回值是一个很常见的模型,比如程序弹出一个窗口,读取用户的输入值,这个值可以很容易的保存在弹出的窗口中,但问题在于如何将这个值传递给弹出窗口的parent.这是一个看似很simple的问 ...

  8. python的窗口处理模块_Python tkinter模块弹出窗口及传值回到主窗口操作详解

    本文实例讲述了Python tkinter模块弹出窗口及传值回到主窗口操作.分享给大家供大家参考,具体如下: 有些时候,我们需要使用弹出窗口,对程序的运行参数进行设置.有两种选择 一.标准窗口 如果只 ...

  9. java在面板中点击按钮后弹出对话框

    1 import javax.swing.*; 2 import java.awt.event.*; 3 import java.awt.*; 4 5 public class ShowDIalog ...

最新文章

  1. 跨域产生的原因和解决方法_ABS注塑制品产生色差的原因及解决方法
  2. FPGA之道(23)VHDL的signal、variable与constant
  3. 大数据分析中国冬季重度雾霾的成因(二)
  4. UIButton中的三个UIEdgeInsets属性
  5. tomcat安装与项目部署
  6. C - Insertion Sort Gym - 101955C(2018icpc沈阳/打表找规律)
  7. spring javafx_带有Spring的JavaFX 2
  8. 阿里王帅回应“马云被印度法院传唤”:马云太难找,要去HHB酒吧试试
  9. oracle truncate闪回数据库恢复
  10. linux下安装apache + subversionSVN_Subversion
  11. App拉起:h5打开app指定页面
  12. 负指数分布的性质_负指数分布.ppt
  13. 数据分析SQL环比增长率、同比增长率
  14. java 货币格式 转换_Java 转换货币形式
  15. TANRIC:肿瘤相关lncRNA数据库
  16. AutoCAD家具设计入门到精通视频教程
  17. 印象笔记如何分享链接_几步搞懂印象笔记的链接功能
  18. 盘点国内好用的企业网盘
  19. python定义一个类savingaccount表示银行账户_创建一个SavingAccount类
  20. 艺龙私有化,携程与腾讯眉来眼去

热门文章

  1. GitHub 长期被中国人“霸榜”?看完榜单我呆了...
  2. 新人入职,上午写了一段代码,下午就被开除了
  3. 【升级包】jeecg_online 支持主子表列表展示风格模板升级包,简易升级
  4. JEECG v3.0.beta发布,基于代码生成器的智能开发平台
  5. seasar一般性配置
  6. SpringBoot2 整合 Zookeeper组件,管理架构中服务协调
  7. BeautifulSoup 用法总结
  8. ThinkPHP/---合并数组后按时间排序
  9. 推荐两款 GTD 工具
  10. 1.4. Open Source and License