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()
### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逢生博客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值