C语言桌面应用开发GTK3 Glade GTK主题

GTK 简介

GTK(GIMP Toolkit)是一套用于创建图形用户界面(GUI)的开发工具包。它最初是为GNU Image Manipulation Program(GIMP)项目而开发的,但后来发展成为一个独立的开源项目,被广泛用于许多不同的应用程序。

以下是GTK的一些关键特点和信息:

  • 跨平台性: GTK是跨平台的,可以在多个操作系统上运行,包括Linux、Windows和macOS。这使得开发人员能够创建一次界面设计,然后在不同平台上部署。

  • 编程语言支持: GTK最初是用C编写的,但它支持多种编程语言,包括C、C++、Python、Vala等。这使得开发者可以选择最适合他们的语言来构建应用程序。

  • 插件式架构: GTK的设计是模块化的,允许开发者使用或替换特定的组件,以满足他们应用程序的需求。这使得GTK非常灵活,适用于各种不同类型的应用。

  • Widgts和控件: GTK包括丰富的窗口小部件(Widgets)和控件,如按钮、文本框、列表框等,使开发者能够轻松地构建各种用户界面。

  • 主题和外观: GTK提供了主题支持,允许开发者定制应用程序的外观和感觉,以适应不同的设计风格和用户喜好。

  • GLib和Pango: GTK使用GLib作为其底层的通用工具库,提供一些数据结构和函数。Pango用于文本渲染,支持复杂的文本布局和国际化。

GTK Github

GTK 官网

  • https://www.gtk.org/
  • https://www.gtk.org/docs/
  • https://docs.gtk.org/gtk4/

GTK 组件文档

  • https://docs.gtk.org/gtk4/index.html#classes
  • https://docs.gtk.org/gtk4/class.Button.html

GTK 官方示例

github最新版本是 gtk4

git clone https://github.com/GNOME/gtk.git
# 创建 dist
mkdir dist
# 测试代码目录
cd tests
gcc $(pkg-config --cflags gtk4) -o ../dist/testdropdown  testdropdown.c $(pkg-config --libs gtk4)
# 运行程序
../dist/testdropdown

GTK 开发环境

注: 以下操作均在 Mac 环境

xcode-select --install
brew install pkg-config
# pkgconfig 路径
find / -name pkgconfig
# 是否支持GTK+
brew search gtk
brew install gtk+3
# 验证 gtk+3
pkg-config --cflags --libs gtk+-3.0

配置环境变量

# 检查 pkgconfig 路径
find / -name pkgconfig
# 将以上路径添加到环境变量中(.bash_profile 或 .zshrc)
vim ~/.zshrc
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/:$PKG_CONFIG_PATH
source ~/.zshrc

安装 Glade

Glade是一个用于创建GTK图形用户界面的用户界面构建器。它允许开发者通过可视化方式设计和布局GUI元素,而不必手动编写代码。Glade生成XML格式的描述文件,描述了用户界面的结构和属性。然后,这个XML文件可以由程序加载和解释,从而创建用户界面。

  • 可视化设计:Glade提供了一个直观的图形用户界面,允许用户通过拖放方式设计和布局界面元素,无需手动编写代码。
  • 生成XML描述文件:设计完成后,Glade会生成一个XML格式的描述文件,其中包含了用户界面的结构和属性信息。
  • 与多种编程语言兼容:由于生成的描述文件是基于XML的,因此可以与多种编程语言一起使用。GTK支持多种编程语言,包括C、C++、Python等。
  • 与IDE集成:Glade可以与多个集成开发环境(IDE)一起使用,例如GNOME Builder,以便更方便地进行开发和调试。
  • Glade Github
    • https://github.com/GNOME/glade
    • https://gitlab.gnome.org/GNOME/glade
  • Glade 教程
    • https://developer.gnome.org/
  • 安装 Glade
# 目前版本支持gtk+3
brew install glade
glade --version
# 启动glade
glade
  • Glade 操作界面
    在这里插入图片描述

  • 保存后会生成如下 demo.glade 文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
  <requires lib="gtk+" version="3.24"/>
  <object class="GtkWindow" id="window">
    <property name="width-request">400</property>
    <property name="height-request">200</property>
    <property name="can-focus">False</property>
    <property name="title" translatable="yes">demo</property>
    <child>
      <object class="GtkBox" id="box">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="button">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <property name="margin-start">10</property>
            <property name="margin-end">10</property>
            <property name="margin-top">10</property>
            <property name="margin-bottom">10</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkComboBoxText" id="combobox">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="margin-start">10</property>
            <property name="margin-end">10</property>
            <property name="margin-top">10</property>
            <property name="margin-bottom">10</property>
            <property name="active">0</property>
            <property name="active-id">1</property>
            <items>
              <item id="1" translatable="yes">item1</item>
              <item id="2" translatable="yes">item2</item>
              <item id="3" translatable="yes">item3</item>
              <item id="4" translatable="yes">item4</item>
            </items>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="entry">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="margin-start">10</property>
            <property name="margin-end">10</property>
            <property name="margin-top">10</property>
            <property name="margin-bottom">10</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

完整示例 demo.c

示例使用 gtk+3demo.glade 文件构建界面

#include <gtk/gtk.h>

static void
on_button_clicked (GtkButton *button, gpointer user_data)
{
  g_print ("Hello World\n");
}

static void
on_combobox_changed (GtkComboBox *combobox, gpointer user_data)
{
  gint active_item = gtk_combo_box_get_active (combobox);
  const gchar *active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combobox));
  g_print ("Selected item: %d, active_id: %s\n", active_item, active_id);
}

static void
on_entry_changed (GtkEntry *entry, gpointer user_data)
{
  const gchar *text = gtk_entry_get_text (entry);
  g_print ("Entry Text: %s\n", text);
}

static void
on_entry_activate (GtkEntry *entry, gpointer user_data)
{
  const gchar *text = gtk_entry_get_text (entry);
  g_print ("Entry Text: %s\n", text);
}

int
main (int argc, char **argv)
{
  GtkBuilder *builder = gtk_builder_new ();
  GtkWidget *window;
  GtkWidget *button;
  GtkWidget *combobox;
  GtkWidget *entry;

  gtk_init (&argc, &argv);
  gtk_builder_add_from_file (builder, "demo.glade", NULL);

  window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
  button = GTK_WIDGET (gtk_builder_get_object (builder, "button"));
  combobox = GTK_WIDGET (gtk_builder_get_object (builder, "combobox"));
  entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));

  gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
	
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (button, "clicked", G_CALLBACK (on_button_clicked), NULL);
  g_signal_connect (combobox, "changed", G_CALLBACK (on_combobox_changed), NULL);
  g_signal_connect (entry, "changed", G_CALLBACK (on_entry_changed), NULL);
  g_signal_connect (entry, "activate", G_CALLBACK (on_entry_activate), NULL);

  g_object_unref (G_OBJECT (builder));
  gtk_widget_show (window);

  gtk_main ();
  return 0;
}

运行效果

# 编译demo.c
gcc $(pkg-config --cflags gtk+-3.0) -o demo demo.c $(pkg-config --libs gtk+-3.0)
# 或
gcc -o demo demo.c `pkg-config --cflags --libs gtk+-3.0`

# 执行编译后文件demo
./demo

在这里插入图片描述

GTK 主题

  • https://www.gnome-look.org/browse?cat=135&ord=latest

推荐主题

  • https://www.gnome-look.org/p/1403328

  • https://github.com/vinceliuice/WhiteSur-gtk-theme

  • https://www.gnome-look.org/p/1357889

  • https://github.com/vinceliuice/Orchis-theme

  • https://github.com/vinceliuice/Mojave-gtk-theme

  • https://github.com/paullinuxthemer/Prof-Gnome

全局主题配置

  • GTK主题
# Mac 主题文件解压到.themes
# Windows msys64/mingw64/share/themes
cd ~/.themes

在这里插入图片描述

# 确保文件夹包含诸如 index.theme 文件以及其他图标和资源文件
ls ~/.themes/WhiteSur-Dark
  • 设置主题
# Mac GTK配置文件settings.ini
# Windows msys64/mingw64/etc/gtk-3.0
vim ~/.config/gtk-3.0/settings.ini
# 添加主题
[Settings]
gtk-theme-name = WhiteSur-Dark
gtk-icon-theme-name = WhiteSur-Dark
  • 运行效果
    在这里插入图片描述

  • 更新GTK缓存

gtk-update-icon-cache -f ~/.themes/WhiteSur-Dark

项目主题配置

  • 项目目录结构
├── bin
│   ├── demo
│   ├── demo.c
│   ├── demo.glade
├── etc
│   ├── gtk-3.0
│       ├── settings.ini
├── share 
│   ├── themes
│       ├── Orchis-Dark
│       ├── WhiteSur-Dark
└── 
  • 配置文件指定主题
# 存放主题文件目录
mkdir ./share/themes
# GTK主题配置文件
vim ./etc/gtk-3.0/settings.ini
# 在settings.ini中配置项目主题
[Settings]
gtk-theme-name = WhiteSur-Dark
gtk-icon-theme-name = WhiteSur-Dark
  • 通过代码指定主题

代码优先级高于settings.ini配置文件

int
main (int argc, char **argv)
{
    gtk_init (&argc, &argv);
    // 配置主题
    g_object_set (gtk_settings_get_default (), "gtk-theme-name", "WhiteSur-Dark", NULL);
    g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "WhiteSur-Dark", NULL);
    
}
  • GTK_CSD配置(默认值为0)

GTK_CSD=1时应用样式完全按主题样式

int
main (int argc, char **argv)
{
	gtk_init (&argc, &argv);
	// 设置环境变量,GTK_CSD=1应用主题样式
	putenv ("GTK_CSD=1");
	
}

Mac 电脑上显示效果
在这里插入图片描述

vscode开发环境

  • .vscode/c_cpp_properties.json

GTK+3的includePath目录可以通过Python脚本生成

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/local/include"
            ],
            "defines": [],
            "macFrameworkPath": [
                "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
            ],
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "macos-clang-x64",
            "compilerPath": "/usr/bin/gcc"
        }
    ],
    "version": 4
}

Python脚本列出GTK+3的includePath头文目录

import subprocess
import json


def get_gtk_info():
    try:
        # 运行命令并捕获输出
        output = subprocess.check_output(
            ['pkg-config', '--cflags', '--libs', 'gtk+-3.0']).decode().strip()

        # 解析输出并提取包含路径
        include_paths = []
        for part in output.split():
            if part.startswith("-I"):
                include_paths.append(part[2:])

        # 构建JSON数据
        data = {"includePath": include_paths}

        return data
    except Exception as e:
        print(f"Error getting GTK information: {e}")
        return None


def main():
    gtk_info = get_gtk_info()
    if gtk_info:
        # 输出JSON数据
        print(json.dumps(gtk_info, indent=4))


if __name__ == "__main__":
    main()
  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逢生博客

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值