栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

gtk3基础知识的学习(C语言)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

gtk3基础知识的学习(C语言)

GTK

这里说一下我为什么要学GTK。
当时软工老师让C语言写一个管理系统,体会面向过程的特点。然后我就想着搞个图形界面的会酷点,选择了GTK这个GUI库。
因为我是想在我的windows上使用GTK库,结合我的visual studio2019一起使用,有一点了解的朋友们应该知道,gtk主要就是用在linux上,所以在windows上搞真的问题多多,在网上搜了很多,也没有一个能教在visual studio2019 windows环境下配置GTK的,真的太不容易了。
等过些天我有时间了,会将下面的代码都加上注释,并且配上运行效果图,也会写一篇在visual studio 2019 windows环境下配置GTK的博客,也会记录我使用GTK做软工大作业的过程,有兴趣的朋友可以继续关注我噢!⭐

1. 介绍

是一款纯C的GUI库,简单、强大,Flat API,不需要面向对象的知识,用纯面向过程编写代码。

2. 测试代码
#include 

int main(int argc, char* argv[]) {
    GtkWidget* window;
    GtkWidget* label;

    gtk_init(&argc, &argv);

    
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    
    gtk_window_set_title(GTK_WINDOW(window), "Hello World");

    
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    
    label = gtk_label_new("Hello, World");

    
    gtk_container_add(GTK_CONTAINER(window), label);

    
    gtk_widget_show_all(window);

    
    gtk_main();

    return 0;
}

注意❗:如果涉及到中文字符串,在windows环境下,默认用的是GB2312,会乱码。有以下两种解决方法:

  1. 将代码文件保存为utf-8无签名版(注意一定是无签名版)
  2. 使用我后面的代码,我封装好了函数调用,将中文字符串转为utf-8进行显示输出。(推荐)

这里我说一下为什么推荐,因为utf-8无签名版,在编译小陌白这个中文的时候会莫名出错,编译小陌白呀就不会,我了解的不是很深,所以我这就称它为玄学错误吧,但第二种方法目前在我使用的过程中,没有再产生任何玄学错误,所以,强烈推荐第二种方法。

3. GTK基础 3.1 GTKWidget基本操作和命名规则
  • Widget:控件,主要控件继承体系,儿子具有父亲的能力。

  • Widget基本操作:

    • 因为界面上可能会有多个控件,所以调用方法的时候要传递控件的标识。
    • void gtk_widget_show(widget):显示
    • void gtk_widget_hide(widget):隐藏
    • void gtk_widget_set_sentitive(widget, sensitive):对控件进行禁用或启用。第一个参数是传入要被启用或者禁用的控件,第二个参数是一个boolean值,true就是启用,false就是禁用。
    • void gtk_widget_set_size_request(int widget, int width, int height):设置一个控件的"建议"大小,并不是最终的大小,最终的大小取决于布局的计算。
    • void gtk_widget_destroy(widget):销毁一个控件
  • Window基本操作:

    • gtk_window_set_resizable(window, resizable):设置窗口是否可以缩放。第二个参数是boolean,true就是可以,false是不可以。
    • gtk_window_set_position(window, GTK_WIN_POS_CENTER_ALWAYS):设置窗口显示在屏幕正中央。
    • void gtk_window_maximize(window):最大化
    • void gtk_container_add(container, widget):将一个子控件加到父控件当中。
  • gtk命名规则:

    • 一般以gtk_开头
    • gtk_widget_代表这个函数可以应用于GtkWidget及所有子类。gtk_container_代表这个函数可以应用于GtkContainer及所有子类。
    • gtk_***_new,创建一个***类型的控件并返回它的标识(编号)。
    • gtk_AAA_get_BBB,从AAA类型的控件的标识获得控件的BBB属性的值。
    • gtk_AAA_set_BBB,设置指定标识的类型为AAA的控件的BBB属性的值。
3.2 文本框、按钮和标签
  • 文本框(GtkEntry)

    #include 
    
    int main(int argc, char* argv[]) {
        GtkWidget* window;
    
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "中文");
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
        //1.创建一个行编辑
        GtkWidget* entry = gtk_entry_new();
        //2.设置行编辑显示最大字符的长度
        gtk_entry_set_max_length(GTK_ENTRY(entry), 100);
        //设置行编辑的内容
        gtk_entry_set_text(GTK_ENTRY(entry), "hello entry");
        gtk_container_add(GTK_CONTAINER(window), entry);
    
    
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    
  • 按钮(GtkButton)

    #include 
    
    int main(int argc, char* argv[]) {
        GtkWidget* window;
    
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "中文");
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
        // 创建一个按钮
        GtkWidget* btn1 = gtk_button_new();
        gtk_button_set_label(GTK_BUTTON(btn1), "点我呀");
        gtk_container_add(GTK_CONTAINER(window), btn1);
    
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    
  • 标签(GtkLabel)

    #include 
    
    int main(int argc, char* argv[]) {
        GtkWidget* window;
    
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "中文");
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
        GtkWidget* label = gtk_label_new("你好");
        
        gtk_container_add(GTK_CONTAINER(window), label);
    
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    
3.3 盒子布局(GtkBox)
  • window中最多只能有一个子控件,一般窗口都有很多子控件,怎么办?

    答:使用容器控件。window中放容器控件,其他控件都放容器控件中。

  • 使用:

    #include 
    
    int main(int argc, char* argv[]) {
        GtkWidget* window;
    
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), "中文");
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    
        GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
        GtkWidget* btn1 = gtk_button_new();
        gtk_button_set_label(GTK_BUTTON(btn1), "text");
        gtk_box_pack_start(GTK_BOX(box1), btn1, false, false, 0);
    
        GtkWidget* btn2 = gtk_button_new();
        gtk_button_set_label(GTK_BUTTON(btn2), "text2");
        gtk_box_pack_start(GTK_BOX(box1), btn2, false, false, 0);
    
        gtk_container_add(GTK_CONTAINER(window), box1);
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }
    
3.4 网格布局(GtkGrid)
#include 

int main(int argc, char* argv[]) {
    GtkWidget* window;

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "中文");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* grid = gtk_grid_new();
    GtkWidget* btn1 = gtk_button_new();
    gtk_button_set_label(GTK_BUTTON(btn1), "text");
    gtk_grid_attach(GTK_GRID(grid), btn1, 0, 0, 1, 1); // 左边距,距离顶部边距,宽高

    GtkWidget* btn2 = gtk_button_new();
    gtk_button_set_label(GTK_BUTTON(btn2), "text2");
    gtk_grid_attach(GTK_GRID(grid), btn2, 1, 0, 1, 1);

    GtkWidget* btn3 = gtk_button_new();
    gtk_button_set_label(GTK_BUTTON(btn3), "text3");
    gtk_grid_attach(GTK_GRID(grid), btn3, 0, 1, 2, 2);

    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}
4. GTK深入 4.1 使用信号获得按钮点击消息
#include 
#include 

char* _(char* c)
{ // 解决中文不显示问题
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
int btn1Onclicked(GtkWidget* widget, int data);
GtkWidget* window;

int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);



    GtkWidget* btn1 = gtk_button_new_with_label("ok");
    g_signal_connect(btn1, "clicked", G_CALLBACK(btn1Onclicked), NULL);

    gtk_container_add(GTK_CONTAINER(window), btn1);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

int btn1Onclicked(GtkWidget* widget, int data)
{
    
    gtk_window_set_title(GTK_WINDOW(window), _2("小陌白"));
    return 0;
}

4.2 复选按钮GtkCheckButton
#include 
#include 
int cbAgreeOnClick(GtkWidget* widget, int data);
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
GtkWidget* cbAgree;
GtkWidget* btnInstall;
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

    cbAgree = gtk_check_button_new_with_label(_2("我同意"));
    gtk_box_pack_start(GTK_BOX(box1), cbAgree, false, false, 0);
    g_signal_connect(cbAgree, "clicked", G_CALLBACK(cbAgreeOnClick), NULL);

    btnInstall = gtk_button_new_with_label(_2("安装"));
    gtk_box_pack_start(GTK_BOX(box1), btnInstall, false, false, 0);
    gtk_widget_set_sensitive(btnInstall, false);
    //GtkWidget* cb1 = gtk_check_button_new();
    //gtk_button_set_label(GTK_BUTTON(cb1), _2("男"));
    
    // printf("%d", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cb1)));



    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

int cbAgreeOnClick(GtkWidget* widget, int data)
{
    int checked = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cbAgree));
    gtk_widget_set_sensitive(btnInstall, checked);
    return 0;
}
4.3 单选按钮GtkRadioButton
#include 
#include 
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

    GtkWidget* rbMale = gtk_radio_button_new_with_label(NULL, _2("男"));
    GtkWidget* rbFeMale = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(rbMale), _2("女"));
    gtk_box_pack_start(GTK_BOX(box1), rbMale, false, false, 0);
    gtk_box_pack_start(GTK_BOX(box1), rbFeMale, false, false, 0);

    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

4.4 Label和Entry的更多函数
#include 
#include 
int btnCheckedOnClicked(GtkWidget* widget, int data);
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
GtkWidget* entryName;
GtkWidget* btnCheck;
GtkWidget* labelResult;
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    entryName = gtk_entry_new();
    gtk_entry_set_max_length(GTK_ENTRY(entryName), 5); // 限制输入的最大长度
    gtk_entry_set_visibility(GTK_ENTRY(entryName), false); // 设置为密码框的风格
    btnCheck = gtk_button_new_with_label(_2("鉴定"));
    labelResult = gtk_label_new("");

    g_signal_connect(btnCheck, "clicked", G_CALLBACK(btnCheckedOnClicked), NULL);

    gtk_box_pack_start(GTK_BOX(box1), entryName, false, false, 0);
    gtk_box_pack_start(GTK_BOX(box1), btnCheck, false, false, 0);
    gtk_box_pack_start(GTK_BOX(box1), labelResult, false, false, 0);

    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show(window);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}
int btnCheckedOnClicked(GtkWidget* widget, int data)
{
    const char* name = gtk_entry_get_text(GTK_ENTRY(entryName));
    char msg[50] = { 0 };
    sprintf(msg, _2("经鉴定%s是世界上最帅的人"), name);
    gtk_label_set_text(GTK_LABEL(labelResult), msg);
    return 0;
}

4.5 下拉选择框GtkComboBoxText
#include 
#include 
#include 
int cmbGirlChange(GtkWidget* widget, int data);
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
GtkWidget* cmbGirl;
GtkWidget* labelResult;
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    cmbGirl = gtk_combo_box_text_new();
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbGirl), "hndx", _2("河南大学"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbGirl), "jsj", _2("计算机"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbGirl), "ltq", _2("龙亭区"));
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(cmbGirl), "hndx"); // 设置id="hndx"的行项被默认选中
    
    labelResult = gtk_label_new("");

    g_signal_connect(cmbGirl, "changed", G_CALLBACK(cmbGirlChange), NULL);
    gtk_box_pack_start(GTK_BOX(box1), cmbGirl, false, false, 0);
    gtk_box_pack_start(GTK_BOX(box1), labelResult, false, false, 0);

    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show(window);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}
int cmbGirlChange(GtkWidget* widget, int data)
{
    const char* id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(cmbGirl));
    if (strcmp(id, "hndx") == 0) {// 返回0代表字符串相等
        gtk_label_set_text(GTK_LABEL(labelResult), _2("河南大学欢迎你!"));
    }
    else if (strcmp(id, "龙亭区") == 0) {
        gtk_label_set_text(GTK_LABEL(labelResult), _2("河南省开封市龙亭区欢迎你!"));
    }
    else {
        gtk_label_set_text(GTK_LABEL(labelResult), _2("来一起在计算机的世界遨游吧!"));
    }
    return 0;
}

  • 省市选择器
#include 
#include 
#include 
int cmbProvChange(GtkWidget* widget, int data);
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
GtkWidget* cmbProv; // 省
GtkWidget* cmbCity; // 城市
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

    cmbProv = gtk_combo_box_text_new();
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbProv), "gds", _2("广东省"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbProv), "hns", _2("河南省"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbProv), "hbs", _2("河北省"));
    gtk_combo_box_set_active_id(GTK_COMBO_BOX(cmbProv), "hns"); // 设置id="hndx"的行项被默认选中
    
    cmbCity = gtk_combo_box_text_new();

    g_signal_connect(cmbProv, "changed", G_CALLBACK(cmbProvChange), NULL);
    gtk_box_pack_start(GTK_BOX(box1), cmbProv, false, false, 0);
    gtk_box_pack_start(GTK_BOX(box1), cmbCity, false, false, 0);

    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show(window);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}
int cmbProvChange(GtkWidget* widget, int data)
{
    gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(cmbCity)); // 先清理旧的数据
    const char* id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(cmbProv));
    if (strcmp(id, "hbs") == 0) {
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "hss", _2("衡水市"));
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "bds", _2("保定市"));
    }
    else if (strcmp(id, "gds") == 0) {
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "gzs", _2("广州市"));
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "bds", _2("深圳市"));
    }
    else {
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "kfs", _2("开封市"));
        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cmbCity), "zzs", _2("郑州市"));
    }
    return 0;
}

4.6 工具栏GtkToolBar
#include 
#include 
#include 
char* _(char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}

char* _2(const char* c)
{
    return(g_locale_to_utf8(c, -1, 0, 0, 0));
}
GtkWidget* window;
int main(int argc, char* argv[]) {

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), _2("中文"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget* box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

    GtkWidget* toolbar = gtk_toolbar_new();
    GtkToolItem* btn1 = gtk_tool_button_new(NULL, _2("保存"));
    gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(btn1), GTK_STOCK_SAVE);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn1, 0);

    GtkToolItem* btn2 = gtk_tool_button_new(NULL, _2("退出"));
    gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(btn2), GTK_STOCK_DISCONNECT); // 加图标
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), btn2, 1);

    gtk_box_pack_start(GTK_BOX(box1), toolbar, false, false, 0);

    gtk_container_add(GTK_CONTAINER(window), box1);
    gtk_widget_show(window);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/457498.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号