国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

rust gtk 桌面應(yīng)用 demo

這篇具有很好參考價(jià)值的文章主要介紹了rust gtk 桌面應(yīng)用 demo。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

《精通Rust》里介紹了 GTK+框架的開發(fā),這篇博客記錄并擴(kuò)展一下。rust 可以用于桌面應(yīng)用開發(fā),我還挺驚訝的,大學(xué)的時(shí)候也有學(xué)習(xí)過 VC++,對(duì)桌面編程一直都很感興趣,而且一直有一種妄念,總覺得自己能開發(fā)一款很好用的桌面程序,就和總覺得自己能彩票中大獎(jiǎng)一樣。

rust gtk 桌面應(yīng)用 demo,rust,開發(fā)語(yǔ)言,后端

環(huán)境安裝

可能你會(huì)需要安裝 gtk+3。如果執(zhí)行 cargo build 的時(shí)候提示你找不到 gdk-3.0,那你就需要手動(dòng)安裝一下:
rust gtk 桌面應(yīng)用 demo,rust,開發(fā)語(yǔ)言,后端

不過,也不需要提前安裝這些依賴。當(dāng)我們執(zhí)行 cargo build 編譯的時(shí)候,結(jié)合 rust 的錯(cuò)誤提示進(jìn)行按需安裝是比較穩(wěn)妥的。

功能開發(fā)

在《精通Rust》書中的16章節(jié),書中的 Demo 忽略了一個(gè)非常重要的細(xì)節(jié),就是省略了依賴包的聲明,沒有依賴包的聲明,代碼就缺少了靈魂,編譯都沒有辦法通過。

我在考慮要不要使用 GPT 自動(dòng)生成一下源碼,省的麻煩。自動(dòng)生成代碼還是放到最后吧…可以通過這個(gè)過程來熟悉一下 rust 的函數(shù)。

std::process::exit

這個(gè)函數(shù)并不陌生,使用一個(gè) code 來退出當(dāng)前的進(jìn)程。要想在程序中正常調(diào)用這個(gè)函數(shù),需要導(dǎo)入如下的頭聲明:

use std::process;

gtk::Window

代碼中使用到的組件都來自于 gtk 包,為了方便起見,可以將 gtk 下的聲明全局導(dǎo)入

use gtk::*

std::sync::mpsc::Sender

用來通過 channel 實(shí)現(xiàn)異步通訊的能力,代碼中用來做數(shù)據(jù)通訊,有 send 和對(duì)應(yīng)的 try_recv 的兩個(gè)動(dòng)作。如果我們不引入這個(gè)包,cargo build 還會(huì)給我們另一個(gè)可選建議 glib::Sender,不過這個(gè)函數(shù)的解釋中提到,兩個(gè)方式是類似的。

use std::sync::mpsc::Sender

std::sync::mpsc::Receiver

有消息的發(fā)送,就應(yīng)該有消息的接受

use std::sync::mpsc::Receiver

std::sync::mpsc::channel

函數(shù)用來創(chuàng)建 Sender、Receive,和上面兩個(gè)函數(shù)是一體的,它創(chuàng)建的是一個(gè)異步隊(duì)列。創(chuàng)建同步隊(duì)列需要調(diào)用 std::sync::mpsc::sync_channel方法。

use std::sync::mpsc::channel

mod

rust 在相同的目錄下,不同文件中聲明的結(jié)構(gòu)體是無法相互引用的,需要通過 mod 來解決。mod 主要用來解決項(xiàng)目?jī)?nèi)代碼組織的問題,use mod xxx 會(huì)嘗試去加載當(dāng)前目錄下的 xxx.rs 文件的代碼。

在 main.rs 中的 mod hackernews 就是用來加載 hackernews.rs 中聲明的導(dǎo)出方法或結(jié)構(gòu)體。如果你將這行代碼刪除,程序就會(huì)找不到文件中聲明的 Story 結(jié)構(gòu)體。

use crate::hackernews::Story;

std::sync::Arc

全稱是 Atomically Reference Counted,表示線程安全的引用計(jì)數(shù)器。Arc 表示一個(gè)指針,指向堆空間的 T 值。同時(shí),有一個(gè)附屬的引用計(jì)數(shù)。

use std::sync::Arc;

reqwest::Client

一個(gè)異步的 HTTP 請(qǐng)求客戶端,用來發(fā)送 HTTP 請(qǐng)求。在說明文檔中明確強(qiáng)調(diào):我們不需要使用 Rc 或者 Arc 去包裝這個(gè)類型,內(nèi)部已經(jīng)使用 Arc 包裝過了。

use reqwest::Client;

glib::source::timeout_add

函數(shù)用于固定間隔執(zhí)行閉包函數(shù),示例中的作用是固定間隔嘗試接受消息。我發(fā)現(xiàn),rust 依賴包的做法特別接近 javascript 。

函數(shù)第一個(gè)參數(shù)的類型是 core::time::Duration,這個(gè)時(shí)間概念和 Go 語(yǔ)言相近,不過 rust 表示的是秒+毫秒的單位,構(gòu)造時(shí)間的時(shí)候可以傳遞秒和毫秒兩個(gè)數(shù)值。

use glib::source::timeout_add;

std::ops::ControlFlow

代碼示例中 ControlFlow::Continue(true),目前來看這個(gè) Continue 的含義并不明確,感覺不到它的價(jià)值。

use std::ops::ControlFlow

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

其中,gtk::prelude::BoxExt 屬于 trait 屬性,rust 中的 trait 等同于 go 語(yǔ)言的 interface 類型,也是實(shí)現(xiàn)多態(tài)的手段之一

trait 特性需要明確聲明出來,否則,trait 特性會(huì)被掩藏。所以,下面的兩個(gè)都需要導(dǎo)入:

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

std::future::Future

代碼中使用 reqwest 發(fā)送 http 請(qǐng)求時(shí),send 返回體的類型是 Future,屬于 async 處理方式,包含 Future 類型操作的函數(shù)需要有 async 聲明,await 用來等待返回的結(jié)果。

同一個(gè)線程中,當(dāng)包含多個(gè) async 方法時(shí),這些方法之間就可以實(shí)現(xiàn)“異步”執(zhí)行。如果需要將閉包聲明為 async ,只需要使用 async 關(guān)鍵字聲明代碼塊。

rust gtk 桌面應(yīng)用 demo,rust,開發(fā)語(yǔ)言,后端

發(fā)生的奇怪問題

std::marker::Send

問題:required for Arc<std::sync::mpsc::Sender<Msg>> to implement std::marker::Send
只有實(shí)現(xiàn) Send trait 的類型才可以在線程間安全地轉(zhuǎn)移所有權(quán),而這個(gè)類型明顯沒有實(shí)現(xiàn)。文章來源地址http://www.zghlxwxcb.cn/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();
    }
}

到了這里,關(guān)于rust gtk 桌面應(yīng)用 demo的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 43. 【農(nóng)產(chǎn)品溯源項(xiàng)目前后端Demo】后端二次開發(fā)的重點(diǎn)修改位置

    43. 【農(nóng)產(chǎn)品溯源項(xiàng)目前后端Demo】后端二次開發(fā)的重點(diǎn)修改位置

    前面講過農(nóng)產(chǎn)品溯源Demo比較簡(jiǎn)單,如果想二次開發(fā)需要重點(diǎn)關(guān)注的目錄。 如果要開發(fā)一個(gè)新的API、對(duì)接新的合約,需要有哪些步驟? 定義數(shù)據(jù)結(jié)構(gòu),在domain包新增Class,定義好數(shù)據(jù)字段,定義好get、set方法。domain包沒有業(yè)務(wù)的邏輯實(shí)現(xiàn),只有結(jié)構(gòu)、字段定義。 如果字段首字

    2024年02月02日
    瀏覽(33)
  • Electron桌面應(yīng)用開發(fā)基礎(chǔ)

    Electron 是一種基于 Chromium 和 Node.js 的開源框架,可以用于快速構(gòu)建跨平臺(tái)的桌面應(yīng)用程序。與傳統(tǒng)的桌面應(yīng)用程序不同,Electron 應(yīng)用程序使用 HTML、CSS 和 JavaScript 技術(shù) 棧來實(shí)現(xiàn)界面設(shè)計(jì)和業(yè)務(wù)邏輯,并且具有良好的跨平臺(tái)性能和擴(kuò)展性。 跨平臺(tái)性:Electron 可以在 Windows、M

    2024年02月08日
    瀏覽(23)
  • vue開發(fā)桌面exe應(yīng)用

    Electron-vue Electron-vue搭建vue全家桶+Element UI客戶端(一) 如何使用Vue.js構(gòu)建桌面應(yīng)用程序

    2024年02月10日
    瀏覽(17)
  • C# 開發(fā)桌面應(yīng)用簡(jiǎn)單介紹

    C# 開發(fā)桌面應(yīng)用簡(jiǎn)單介紹

    一. C#使用場(chǎng)景介紹 C#是微軟公司發(fā)布的一種由C和C++衍生出來的面向?qū)ο蟮木幊陶Z(yǔ)言、運(yùn)行于.NET Framework和.NET Core(完全開源,跨平臺(tái))之上的高級(jí)程序設(shè)計(jì)語(yǔ)言。 二.?開發(fā)流程 1.?創(chuàng)建項(xiàng)目:打開Visual Studio后右側(cè)選擇“創(chuàng)建新項(xiàng)目”,然后選擇“C#?Windows窗體應(yīng)用”即可創(chuàng)建桌

    2024年02月05日
    瀏覽(17)
  • Rust軟件外包開發(fā)語(yǔ)言的特點(diǎn)

    Rust軟件外包開發(fā)語(yǔ)言的特點(diǎn)

    Rust 是一種系統(tǒng)級(jí)編程語(yǔ)言,強(qiáng)調(diào)性能、安全性和并發(fā)性的編程語(yǔ)言,適用于廣泛的應(yīng)用領(lǐng)域,特別是那些需要高度可靠性和高性能的場(chǎng)景。下面和大家分享 Rust 語(yǔ)言的一些主要特點(diǎn)以及適用的場(chǎng)合,希望對(duì)大家有所幫助。北京木奇移動(dòng)技術(shù)有限公司,專業(yè)的軟件外包開發(fā)公

    2024年02月12日
    瀏覽(23)
  • springboot開發(fā)PC端桌面應(yīng)用

    springboot開發(fā)PC端桌面應(yīng)用

    ?一、需求描述: 1、要求桌面能在window、Linux和macos系統(tǒng)上運(yùn)行 2、用戶自定義數(shù)據(jù)篩選策略,策略可通過excel導(dǎo)入導(dǎo)出 3、選擇多個(gè)excel文件通過策略過濾生成新的excel 二、技術(shù)選型及集成環(huán)境配置: 1、PC端跨平臺(tái)直接選用javafx來作為桌面開發(fā) 2、動(dòng)態(tài)數(shù)據(jù)規(guī)則使用drools以及內(nèi)

    2024年02月11日
    瀏覽(55)
  • 桌面應(yīng)用程序開發(fā)攻略(初步了解)

    ????????桌面應(yīng)用開發(fā) 是指為桌面計(jì)算機(jī)或其他類似設(shè)備(如服務(wù)器)開發(fā)軟件應(yīng)用程序的過程。桌面應(yīng)用通常是獨(dú)立于瀏覽器運(yùn)行的,并且可以在操作系統(tǒng)的桌面或應(yīng)用程序菜單中找到。桌面應(yīng)用可以使用各種編程語(yǔ)言開發(fā),包括C++、Java、C#和Python等。桌面應(yīng)用的開發(fā)

    2024年02月09日
    瀏覽(22)
  • 桌面應(yīng)用開發(fā)有哪些主流框架?

    桌面應(yīng)用開發(fā)有哪些主流框架?

    受益于開源技術(shù)的發(fā)展,以及響應(yīng)快速開發(fā)的實(shí)際業(yè)務(wù)需求,跨平臺(tái)開發(fā)不僅限于移動(dòng)端跨平臺(tái),桌面端雖然在市場(chǎng)應(yīng)用方面場(chǎng)景不像移動(dòng)端那么豐富,但也有市場(chǎng)的需求。 相對(duì)于個(gè)人開發(fā)者而言,跨平臺(tái)框架的使用,主要為了滿足以下三個(gè)主要能力: 生產(chǎn)力提升 :框架能

    2024年02月05日
    瀏覽(21)
  • 建站系列(六)--- 后端開發(fā)語(yǔ)言

    建站系列(一)— 網(wǎng)站基本常識(shí) 建站系列(二)— 域名、IP地址、URL、端口詳解 建站系列(三)— 網(wǎng)絡(luò)協(xié)議 建站系列(四)— Web服務(wù)器之Apache、Nginx 建站系列(五)— 前端開發(fā)語(yǔ)言之HTML、CSS、JavaScript 建站系列(六)— 后端開發(fā)語(yǔ)言 建站系列(七)— 常用前后端框架

    2024年02月09日
    瀏覽(24)
  • Python桌面應(yīng)用開發(fā)之PyQt

    Python桌面應(yīng)用開發(fā)之PyQt

    Tkinter:優(yōu)勢(shì)是免安裝、相對(duì)簡(jiǎn)單,缺點(diǎn)是功能少,無界面設(shè)計(jì)工具。 PyQT:使用率高,功能最為強(qiáng)大,代碼可維護(hù)性和易讀性高。 WxPython:介于Tkinter和PyQT之間,相當(dāng)于壓縮版QT。 總結(jié):三種框架各有優(yōu)劣,有時(shí)間可以全部學(xué)習(xí),并不復(fù)雜。如果只選一種,這里推薦使用最主

    2024年02月13日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包