rust gtk 桌面应用 demo

这篇具有很好参考价值的文章主要介绍了rust gtk 桌面应用 demo。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

《精通Rust》里介绍了 GTK+框架的开发,这篇博客记录并扩展一下。rust 可以用于桌面应用开发,我还挺惊讶的,大学的时候也有学习过 VC++,对桌面编程一直都很感兴趣,而且一直有一种妄念,总觉得自己能开发一款很好用的桌面程序,就和总觉得自己能彩票中大奖一样。

rust gtk 桌面应用 demo,rust,开发语言,后端

环境安装

可能你会需要安装 gtk+3。如果执行 cargo build 的时候提示你找不到 gdk-3.0,那你就需要手动安装一下:
rust gtk 桌面应用 demo,rust,开发语言,后端

不过,也不需要提前安装这些依赖。当我们执行 cargo build 编译的时候,结合 rust 的错误提示进行按需安装是比较稳妥的。

功能开发

在《精通Rust》书中的16章节,书中的 Demo 忽略了一个非常重要的细节,就是省略了依赖包的声明,没有依赖包的声明,代码就缺少了灵魂,编译都没有办法通过。

我在考虑要不要使用 GPT 自动生成一下源码,省的麻烦。自动生成代码还是放到最后吧…可以通过这个过程来熟悉一下 rust 的函数。

std::process::exit

这个函数并不陌生,使用一个 code 来退出当前的进程。要想在程序中正常调用这个函数,需要导入如下的头声明:

use std::process;

gtk::Window

代码中使用到的组件都来自于 gtk 包,为了方便起见,可以将 gtk 下的声明全局导入

use gtk::*

std::sync::mpsc::Sender

用来通过 channel 实现异步通讯的能力,代码中用来做数据通讯,有 send 和对应的 try_recv 的两个动作。如果我们不引入这个包,cargo build 还会给我们另一个可选建议 glib::Sender,不过这个函数的解释中提到,两个方式是类似的。

use std::sync::mpsc::Sender

std::sync::mpsc::Receiver

有消息的发送,就应该有消息的接受

use std::sync::mpsc::Receiver

std::sync::mpsc::channel

函数用来创建 Sender、Receive,和上面两个函数是一体的,它创建的是一个异步队列。创建同步队列需要调用 std::sync::mpsc::sync_channel方法。

use std::sync::mpsc::channel

mod

rust 在相同的目录下,不同文件中声明的结构体是无法相互引用的,需要通过 mod 来解决。mod 主要用来解决项目内代码组织的问题,use mod xxx 会尝试去加载当前目录下的 xxx.rs 文件的代码。

在 main.rs 中的 mod hackernews 就是用来加载 hackernews.rs 中声明的导出方法或结构体。如果你将这行代码删除,程序就会找不到文件中声明的 Story 结构体。

use crate::hackernews::Story;

std::sync::Arc

全称是 Atomically Reference Counted,表示线程安全的引用计数器。Arc 表示一个指针,指向堆空间的 T 值。同时,有一个附属的引用计数。

use std::sync::Arc;

reqwest::Client

一个异步的 HTTP 请求客户端,用来发送 HTTP 请求。在说明文档中明确强调:我们不需要使用 Rc 或者 Arc 去包装这个类型,内部已经使用 Arc 包装过了。

use reqwest::Client;

glib::source::timeout_add

函数用于固定间隔执行闭包函数,示例中的作用是固定间隔尝试接受消息。我发现,rust 依赖包的做法特别接近 javascript 。

函数第一个参数的类型是 core::time::Duration,这个时间概念和 Go 语言相近,不过 rust 表示的是秒+毫秒的单位,构造时间的时候可以传递秒和毫秒两个数值。

use glib::source::timeout_add;

std::ops::ControlFlow

代码示例中 ControlFlow::Continue(true),目前来看这个 Continue 的含义并不明确,感觉不到它的价值。

use std::ops::ControlFlow

gtk::Box | gtk::prelude::BoxExt

其中,gtk::prelude::BoxExt 属于 trait 属性,rust 中的 trait 等同于 go 语言的 interface 类型,也是实现多态的手段之一

trait 特性需要明确声明出来,否则,trait 特性会被掩藏。所以,下面的两个都需要导入:

use gtk::Box;
use gtk::prelude::BoxExt;

std::future::Future

代码中使用 reqwest 发送 http 请求时,send 返回体的类型是 Future,属于 async 处理方式,包含 Future 类型操作的函数需要有 async 声明,await 用来等待返回的结果。

同一个线程中,当包含多个 async 方法时,这些方法之间就可以实现“异步”执行。如果需要将闭包声明为 async ,只需要使用 async 关键字声明代码块。

rust gtk 桌面应用 demo,rust,开发语言,后端

发生的奇怪问题

std::marker::Send

问题:required for Arc<std::sync::mpsc::Sender<Msg>> to implement std::marker::Send
只有实现 Send trait 的类型才可以在线程间安全地转移所有权,而这个类型明显没有实现。文章来源地址https://www.toymoban.com/news/detail-603270.html

代码

impl App {
    pub fn new() -> (App, Receiver<Msg>) {
        if gtk::init().is_err() {
            println!("Failed to init hews window");
            process::exit(1);
        }

        let (tx, rx) = channel();
        let window = gtk::Window::new(gtk::WindowType::Toplevel);
        let sw = ScrolledWindow::new(None, None);
        let stories = gtk::Box::new(gtk::Orientation::Vertical, 20);
        let spinner = gtk::Spinner::new();
        let header = Header::new(stories.clone(), tx.clone());

        stories.pack_start(&spinner, false, false, 2);
        sw.add(&stories);
        window.add(&sw);
        window.set_default_size(600, 350);
        window.set_titlebar(&header.header);

        window.connect_delete_event(move |_, _| {
            main_quit();
            Inhibit(false);
        });
    }

    pub fn launch(&self, rx: Receiver<Msg>) {
        self.window.show_all();
        let client = Arc::new(reqwest::Client::new());
        self.fetch_posts(client.clone());
        self.run_event_loop(rx, client);
    }

    fn fetch_posts(&self, client: Arc<Client>) {
        self.spinner.start();
        self.tx.send(Msg::Loading).unwrap();
        let tx_clone = self.tx.clone();
        top_stories(client, 10, &tx_clone);
    }

    fn run_event_loop(&self, rx: Receiver<Msg>, client: Arc<Client>) {
        let container = self.stories.clone();
        let spinner = self.spinner.clone();
        let header = self.header.clone();
        let tx_clone = self.tx.clone();

        timeout_add(100, move || {
            match rx.try_recv() {
                Ok(Msg::NewStory(s)) => App::render_story(s, &container),
                Ok(Msg::Loading) => header.disable_refresh(),
                Ok(Msg::Loaded) => {
                    spinner.stop();
                    header.enable_refresh();
                }
                Ok(Msg::Refresh) => {
                    spinner.start();
                    spinner.show();
                    (&tx_clone).send(Msg::Loading).unwrap();
                    top_stories(client.clone(), 10, &tx_clone)
                }
                Err(_) => {}
            }
            Continue(true)
        });

        gtk::main();
    }

    fn render_story(s: Stroy, stories: &gtk::Box) {
        let title_with_score = format!("{} ({})", s.title, s.score);
        let label = gtk::Label::new(&*title_with_score);
        let story_url = s.url.unwrap_or("N/A".to_string());
        let link_label = gtk::Label::new(&*story_url);
        let label_markup = format!("<a href=\"{}\">{}</a>", story_url, story_url);

        link_label.set_markup(&label_markup);
        stories.pack_start(&label, false, false, 2);
        stories.pack_start(&link_label, false, false, 2);
        stories.show_all();
    }
}

到了这里,关于rust gtk 桌面应用 demo的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 43. 【农产品溯源项目前后端Demo】后端二次开发的重点修改位置

    前面讲过农产品溯源Demo比较简单,如果想二次开发需要重点关注的目录。 如果要开发一个新的API、对接新的合约,需要有哪些步骤? 定义数据结构,在domain包新增Class,定义好数据字段,定义好get、set方法。domain包没有业务的逻辑实现,只有结构、字段定义。 如果字段首字

    2024年02月02日
    浏览(53)
  • vue开发桌面exe应用

    Electron-vue Electron-vue搭建vue全家桶+Element UI客户端(一) 如何使用Vue.js构建桌面应用程序

    2024年02月10日
    浏览(43)
  • Electron桌面应用开发基础

    Electron 是一种基于 Chromium 和 Node.js 的开源框架,可以用于快速构建跨平台的桌面应用程序。与传统的桌面应用程序不同,Electron 应用程序使用 HTML、CSS 和 JavaScript 技术 栈来实现界面设计和业务逻辑,并且具有良好的跨平台性能和扩展性。 跨平台性:Electron 可以在 Windows、M

    2024年02月08日
    浏览(43)
  • C# 开发桌面应用简单介绍

    一. C#使用场景介绍 C#是微软公司发布的一种由C和C++衍生出来的面向对象的编程语言、运行于.NET Framework和.NET Core(完全开源,跨平台)之上的高级程序设计语言。 二. 开发流程 1. 创建项目:打开Visual Studio后右侧选择“创建新项目”,然后选择“C# Windows窗体应用”即可创建桌

    2024年02月05日
    浏览(55)
  • Rust软件外包开发语言的特点

    Rust 是一种系统级编程语言,强调性能、安全性和并发性的编程语言,适用于广泛的应用领域,特别是那些需要高度可靠性和高性能的场景。下面和大家分享 Rust 语言的一些主要特点以及适用的场合,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公

    2024年02月12日
    浏览(47)
  • 桌面应用开发有哪些主流框架?

    受益于开源技术的发展,以及响应快速开发的实际业务需求,跨平台开发不仅限于移动端跨平台,桌面端虽然在市场应用方面场景不像移动端那么丰富,但也有市场的需求。 相对于个人开发者而言,跨平台框架的使用,主要为了满足以下三个主要能力: 生产力提升 :框架能

    2024年02月05日
    浏览(38)
  • 桌面应用程序开发攻略(初步了解)

            桌面应用开发 是指为桌面计算机或其他类似设备(如服务器)开发软件应用程序的过程。桌面应用通常是独立于浏览器运行的,并且可以在操作系统的桌面或应用程序菜单中找到。桌面应用可以使用各种编程语言开发,包括C++、Java、C#和Python等。桌面应用的开发

    2024年02月09日
    浏览(45)
  • springboot开发PC端桌面应用

     一、需求描述: 1、要求桌面能在window、Linux和macos系统上运行 2、用户自定义数据筛选策略,策略可通过excel导入导出 3、选择多个excel文件通过策略过滤生成新的excel 二、技术选型及集成环境配置: 1、PC端跨平台直接选用javafx来作为桌面开发 2、动态数据规则使用drools以及内

    2024年02月11日
    浏览(55)
  • 建站系列(六)--- 后端开发语言

    建站系列(一)— 网站基本常识 建站系列(二)— 域名、IP地址、URL、端口详解 建站系列(三)— 网络协议 建站系列(四)— Web服务器之Apache、Nginx 建站系列(五)— 前端开发语言之HTML、CSS、JavaScript 建站系列(六)— 后端开发语言 建站系列(七)— 常用前后端框架

    2024年02月09日
    浏览(40)
  • 如何使用Java进行桌面应用的开发?

    使用Java进行桌面应用的开发可以借助JavaFX或Swing框架。下面为你提供一些基本的步骤: 安装Java开发工具包(JDK):首先,确保你已经安装了Java开发工具包(JDK),并正确配置了环境变量。 选择GUI框架:Java提供了两个主要的桌面GUI框架:JavaFX和Swing。JavaFX是Oracle推荐的最新的

    2024年02月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包