You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Rust Iced 0.12升级到0.14的代码改造及报错解决求助

Rust Iced 0.12升级到0.14的代码改造及报错解决求助

我有一段在Iced 0.12版本中可以正常运行的代码,现在想要把它升级到Iced 0.14,但遇到了几个编译错误,希望能得到大家的帮助。

原代码(Iced 0.12)

use iced::widget::{container, text};
use iced::{Application, Color, Command, Element, Settings, Subscription, Theme};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

#[derive(Debug, Clone)]
pub(crate) enum Message {
    ColorChanged(ColorState),
}

#[derive(Debug, Clone, Copy, PartialEq)]
enum ColorState {
    Red,
    Orange,
    Green,
}

impl ColorState {
    fn next(self) -> Self {
        match self {
            ColorState::Red => ColorState::Orange,
            ColorState::Orange => ColorState::Green,
            ColorState::Green => ColorState::Red,
        }
    }

    fn to_color(self) -> Color {
        match self {
            ColorState::Red => Color::from_rgb(0.8, 0.0, 0.0),
            ColorState::Orange => Color::from_rgb(1.0, 0.5, 0.0),
            ColorState::Green => Color::from_rgb(0.0, 0.8, 0.0),
        }
    }

    fn to_text(self) -> &'static str {
        match self {
            ColorState::Red => "Red",
            ColorState::Orange => "Orange",
            ColorState::Green => "Green",
        }
    }
}

struct ColorCycleApp {
    current_color: ColorState,
    color_state: Arc<Mutex<ColorState>>,
}

impl Application for ColorCycleApp {
    type Message = Message;
    type Theme = Theme;
    type Executor = iced::executor::Default;
    type Flags = ();

    fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
        let color_state = Arc::new(Mutex::new(ColorState::Red));

        // Start the background thread
        let color_state_clone = Arc::clone(&color_state);
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_secs(2));

                let mut state = color_state_clone.lock().unwrap();
                *state = state.next();
                println!("Thread changed color to: {:?}", *state);
            }
        });

        (
            Self {
                current_color: ColorState::Red,
                color_state,
            },
            Command::none(),
        )
    }

    fn title(&self) -> String {
        String::from("My GUI")
    }

    fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
        match message {
            Message::ColorChanged(new_color) => {
                self.current_color = new_color;
                println!("New color: {:?}", new_color);
                Command::none()
            }
        }
    }

    fn view(&'_ self) -> Element<'_, Self::Message> {
        let current_color = self.current_color.to_color();

        let label = text(self.current_color.to_text()).size(48);

        let colored_container = container(label)
            .width(iced::Length::Fill)
            .height(iced::Length::Fill)
            .center_x()
            .center_y()
            .style(move |_theme: &Theme| container::Appearance {
                background: Some(iced::Background::Color(current_color)),
                ..Default::default()
            });

        colored_container.into()
    }

    fn subscription(&self) -> Subscription<Self::Message> {
        let color_state = Arc::clone(&self.color_state);

        iced::subscription::unfold("color_monitor", ColorState::Red, move |last_color| {
            let color_state = Arc::clone(&color_state);
            async move {
                loop {
                    std::thread::sleep(Duration::from_millis(100));

                    let current_color = {
                        let state = color_state.lock().unwrap();
                        *state
                    };

                    if current_color != last_color {
                        return (Message::ColorChanged(current_color), current_color);
                    }
                }
            }
        })
    }
}

fn main() -> iced::Result {
    ColorCycleApp::run(Settings {
        window: iced::window::Settings {
            size: iced::Size::new(400.0, 300.0),
            ..Default::default()
        },
        ..Default::default()
    })
}

遇到的编译错误

  • 未解析的导入 iced::Command(Rust 提示我可以使用 std::process::Commandtokio::process::Command,但这显然不是我需要的)
  • 无法解析:在 iced 根模块中找不到 subscription 相关内容
  • container 模块中找不到结构体、变体或联合类型 Appearance
  • 编译器提示“期望 trait,却找到结构体 Application

已尝试的解决方向

目前我试过用iced::Program trait来替代原来的Application,也尝试用Container::Style来替换原来的Appearance,但还没能完全解决所有问题,希望有人能帮忙梳理下Iced 0.12到0.14的关键变化,以及这段代码需要做哪些调整才能正常运行。

备注:内容来源于stack exchange,提问作者Josh.h

火山引擎 最新活动