GTK开发(二)控件和布局
前言
之前已经介绍个gtk,以及做一个窗口,下面接着学习gtk开发相关知识,有关控件和布局,进而做一个漂亮的页面。
一、控件
1、控件介绍
控件是对数据和方法的封装。控件有自己的属性和方法。属性是指控件的特征。方法是指控件的一些简单而可见的功能。
在GTK+中,控件大体上可以分为两类,容器控件和非容器控件;
非容器控件不可以容纳别的控件,包括诸如文字标签、图像、单行输入等图形界面编程中的最基本的元素
容器控件:它可以容纳别的控件,我们可以理解为盒子,盒子拿来装东西。容器控件又分为两类,一类只能容纳一个控件,如窗口,按钮;另一类能容纳多个控件,如布局控件。
前面我们写的空白窗口是能容纳一个控件的控件,现在我们要做的是,给这个窗口添加一个按钮。
首先,我们需要创建一个按钮,然后需要把按钮添加到窗口,接着,显示按钮控件。
需要的函数:
创建一个带文件的按钮:
GtkWidget* gtk_button_new_with_label(const gchar* label);
label:按钮上的字符串类型,gchar相当于C语言的char
返回值:按钮控件指针
获取按键上的文本
const gchar* gtk_button_get_label(GtkButton* button);
把控件包含在窗口中
void gtk_container_add(GtkContainer * container,GtkWidget* widget);
container:容纳控件的容器
widget:要添加的控件
显示控件:
void gtk_widget_show(GtkWidget *widget);
widget:需要显示的控件
2、带按钮的窗口
有了前面的简介很容易创建一个带按钮的窗口
#include <gtk/gtk.h>
#include <stdio.h>
//点击关闭键后不退出
int main(int argc, char *argv[]) //在做gtk的时候要将const删除
{
//GTK的开发流程
//环境的初始化
gtk_init(&argc,&argv);
//创建一个窗口的控件来显示
//gtk_window_new () 创建新的窗口 返回类型 GtkWidget *;
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//控件类型 变量 创建新的窗口 顶置有边框
GtkWidget* button = gtk_button_new_with_label("你好,Gtk!");
gtk_container_add(GTK_CONTAINER(window),button);
//显示这个窗口
gtk_widget_show_all(window);
//信号 ,当点击关闭时退出程序
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
//信号连接函数 谁发出的信号 发出的什么样的信号 回调函数(系统自己定义的退出函数) 回调函数的参数
//主事件循环
gtk_main();
return 0;
}
运行之后会发现按下按键后无功能;要想按钮实现功能就需要添加按钮信号,实现功能.这就用到信号函数:
g_signal_connect(谁发出的信号,发出的什么信号,回调函数G_CALLBACK,回调函数的参数)
窗口关闭:destroy,delete-event
按键:pressed,clicked
g_signal_connect(button,“pressed”,G_CALLBACK(自己定义),“gtk”);
//按钮的信号函数是有规则的,有模板的
void 函数名(GtkButton* button ,gpointer user_data); (void*–>使用强转)
#include <gtk/gtk.h>
#include <stdio.h>
//按钮信号区
void haha(GtkButton* button,gpointer user_data);
//点击关闭键后不退出
int main(int argc, char *argv[]) //在做gtk的时候要将const删除
{
//GTK的开发流程
//环境的初始化
gtk_init(&argc,&argv);
//创建一个窗口的控件来显示
//gtk_window_new () 创建新的窗口 返回类型 GtkWidget *;
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//控件类型 变量 创建新的窗口 顶置有边框
GtkWidget* button = gtk_button_new_with_label("请戳我!");
gtk_container_add(GTK_CONTAINER(window),button);
//显示这个窗口
gtk_widget_show_all(window);
//信号 ,当点击关闭时退出程序
g_signal_connect(button,"pressed",G_CALLBACK(haha),"疼");
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
//信号连接函数 谁发出的信号 发出的什么样的信号 回调函数(系统自己定义的退出函数) 回调函数的参数
//主事件循环
gtk_main();
return 0;
}
//gpointer -->void *
void haha(GtkButton* button,gpointer user_data)
{
printf("%s\n",gtk_button_get_label(button));
printf("%s\n",(char*)user_data);
}
结果看下图
3、其他补充
void gtk_container_add(GtkContainer *container, GtkWidget *widget);这个函数是把按钮添加到窗口容器里,widget为按钮指针(以上代码的button),container为窗口指针(以上代码的window)
需要注意的是,创建的窗口(window)返回值为GtkWidget *类型,而gtk_container_add()的第一个参数为GtkContainer *类型,而 GtkWidget *类型的变量为指向任何控件的万能指针,所以,在函数传参时,需要根据参数类型进行相应的转换,如:gtk_container_add( (GtkContainer *)window, button);
C语言里,我们常用这种方法转换。
在GTK中,很多内部变量指针类型转换都定义了宏定义,如:
#define GTK_CONTAINER(x) (GtkContainer *)(x)
所以,可以这么写:gtk_container_add(GTK_CONTAINER(window), button);
那么,哪个类型对应哪个宏定义呢?
把要转换类型名字全部变为大写,同时,单词和单词之间以下划线“_”连接,然后,这个名字就是宏定义的名字,如,(GtkButton *)x用宏定义的方法为 GTK_BUTTON(x)。
gtk_widget_show(button);// 显示按钮
gtk_widget_show(window);// 显示窗口
如果,窗口里有多个控件要显示,这样一个一个地显示就会比较麻烦,所以,我们用gtk_widg