Rust语言桌面应用开发GTK3 Gtk3-rs Glade

news/2024/9/29 14:01:54 标签: rust, 开发语言, 前端

文章目录

  • GTK-RS
  • Github
  • 官网
  • Rust 教程
  • Rust 环境
  • 安装 GTK
  • 安装 Glade
  • demo.glade 文件
  • 完整示例 main.rs
    • 创建 Rust 项目
    • Cargo.toml 文件
    • main.rs 文件
  • 编译运行
  • GTK主题

GTK-RS

gtk-rs 是一个用于在 Rust 编程语言中使用 GTK 图形用户界面工具包的库。GTK 是一个流行的跨平台 GUI 工具包,用于创建图形界面应用程序,它最初是为 GIMP 图像编辑器开发的,现在广泛用于许多开源和商业应用程序中。

Github

  • https://github.com/gtk-rs/gtk3-rs
  • https://github.com/gtk-rs/gtk4-rs

官网

  • https://gtk-rs.org/
  • https://gtk-rs.org/gtk3-rs/
  • https://gtk-rs.org/gtk4-rs/

Rust 教程

  • https://rustwiki.org/zh-CN/rust-by-example/index.html

Rust 环境

  • 参考我的这篇文章 《使用 Rustup 管理 Rust 版本》

安装 GTK

注: 版本兼容问题,gtk4 目前暂不支持 Glade 推荐安装 gtk3 版本。
gtk3 对应 gtk3-rs 版本
gtk4 对应 gtk4-rs 版本

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 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 文件

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>

完整示例 main.rs

注: gtk3-rs 支持 .glade 文件。

创建 Rust 项目

cargo new demo
  • Rust 项目结构

在这里插入图片描述

Cargo.toml 文件

注: 本章示例使用 GTK3 版本。
https://crates.io/search?q=gtk

在这里插入图片描述

[dependencies]
gtk = { version = "0.18.1", features = ["v3_24"] }

main.rs 文件

rust">use gtk::prelude::*;
use gtk::{gio, glib};
use gtk::{Window, Builder, Button, ComboBox, Entry};

fn main() {
    let application = gtk::Application::new(
        Some("com.gtk-rs.demo"),
        Default::default(),
    );
    application.connect_activate(build_ui);

    // 退出操作的逻辑,并将其与快捷键绑定
    let quit = gio::SimpleAction::new("quit", None);
    quit.connect_activate(
        glib::clone!(@weak application => move |_action, _parameter| {
            application.quit();
        }),
    );
    application.connect_startup(|application| {
        application.set_accels_for_action("app.quit", &["<Primary>Q"]);
    });
    application.add_action(&quit);

    application.run();
}

fn build_ui(application: &gtk::Application) {
    let glade_src = include_str!("demo.glade");
    let builder = Builder::from_string(glade_src);

    let window: Window = builder.object("window").expect("Couldn't get window");
    window.set_application(Some(application));
    window.set_position(gtk::WindowPosition::Center);

    let button: Button = builder.object("button").expect("Couldn't get button");
    button.connect_clicked(move |_| {
        println!("Button clicked!");
    });

    let combobox: ComboBox = builder.object("combobox").expect("Couldn't get combobox");
    combobox.connect_changed(move |combobox| {
        if let Some(index) = combobox.active() {
            println!("ComboBox changed! Selected index: {}", index);
        } else {
            println!("No item selected");
        }        
    });

    let entry: Entry = builder.object("entry").expect("Couldn't get entry");
    entry.connect_changed(move |entry| {
        println!("Entry changed! {}", entry.text());
    });
    entry.connect_activate(move |entry| {
        println!("Entry activate! {}", entry.text());
    });

    window.show_all();
}

编译运行

cargo run

在这里插入图片描述

GTK主题

  • 参考我的这篇文章 《C语言桌面应用开发GTK3 Glade GTK主题》

http://www.niftyadmin.cn/n/5683140.html

相关文章

Java项目实战II基于Java+Spring Boot+MySQL的厨艺交流平台设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在美食文化…

深入理解 `strncat()` 函数:安全拼接字符串

目录&#xff1a; 前言一、 strncat() 函数的基本用法二、 示例代码三、 strncat() 与 strcat() 的区别四、 注意事项五、 实际应用场景总结 前言 在C语言中&#xff0c;字符串操作是编程中非常常见的需求。strncat() 函数是标准库中用于字符串拼接的一个重要函数&#xff0c;…

C++学习,标准库输入输出

<iostream>库是 C 标准库中用于输入输出操作的头文件。C 标准库是 C 编程语言的官方库&#xff0c;它提供了大量的类、函数和对象&#xff0c;可以帮助开发者完成各种编程任务&#xff0c;从简单的输入输出到复杂的数据结构和算法。iostream 是 C 标准库中非常重要的一部…

1.5 测试用例

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 测试用例介绍2 测试用例编写3 案例分析4 执行测试用例 前言 测试用例的设计和编制是软件活动中最重要的工作。本文详细讲解了测试用例的基本概念以及如何编写测试用例。 本篇文…

【傻呱呱】ESXI挂载USB移动硬盘给黑裙扩容

前期准备 ssh连接工具&#xff08;这里我用finalshell&#xff09; 删除移动硬盘分区&#xff08;此操作会删除硬盘内所有数据&#xff0c;注意备份&#xff01;&#xff01;&#xff01;&#xff09; 将需要挂载的usb移动硬盘连接到电脑上&#xff0c;使用分区工具&#xff…

【LeetCode: 227. 基本计算器 II + 栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【Linux学习】【Ubuntu入门】1-2 新建虚拟机ubuntu环境

1.双击打开VMware软件&#xff0c;点击“创建新的虚拟机”&#xff0c;在弹出的中选择“自定义&#xff08;高级&#xff09;” 2.点击下一步&#xff0c;自动识别ubuntu光盘映像文件&#xff0c;也可以点击“浏览”手动选择&#xff0c;点击下一步 3.设置名称及密码后&#xf…

TreeMap源码详解

优质博文&#xff1a;IT-BLOG-CN 背景&#xff1a;昨天有人问我&#xff0c;他想将Map中的Key按照顺序进行遍历&#xff0c;我说直接使用keySet方法获取到Set集合&#xff0c;因为它是集成Collection接口&#xff0c;所以包含了sort方法后遍历取value值即可。但当看到TreeMap的…