はじめに
筆者は、2, 3日ハマったのでメモとして残しておきます。
bevyの0.17以降でウィンドウのアイコンを変えたい人には、参考になるかもしれません。
環境
| 項目 | バージョン |
|---|---|
| OS | Windows11 HomeEdition |
| rustc | 1.91.1 |
| bevy | 0.17.0 |
コード
Cargo.toml
name = "test_bevy"
version = "0.1.0"
edition = "2024"
[dependencies]
bevy = "0.17.0"
bevy_winit = "0.17.0"
reqwest = { version = "0.12.24", features = ["blocking"] }
image = "0.25.9"
winit = "0.30.12"
src/main.rs
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
fn setup(
mut commands: Commands,
_: bevy::ecs::system::NonSendMarker,
) {
commands.spawn(Camera2d::default());
let url = "https://img.icons8.com/?size=64&id=20699&format=png&color=000000";
let icon = load_icon_from_url(url);
bevy::winit::WINIT_WINDOWS.with_borrow_mut(|winit_windows| {
if winit_windows.windows.is_empty(){return;}
for window in winit_windows.windows.values(){
println!("{:?}", window);
window.set_window_icon(icon.clone());
}
});
}
fn load_icon_from_url(url: &str) -> Option<winit::window::Icon>{
let Ok(response) = reqwest::blocking::get(url) else {return None};
let bytes = response.bytes().unwrap();
let Ok(img) = image::ImageReader::new(std::io::Cursor::new(bytes))
.with_guessed_format() else {return None};
let Ok(dyim) = img.decode() else {return None};
let pixels = dyim.as_bytes().to_vec();
let width = dyim.width();
let height = dyim.height();
let Ok(icon) = winit::window::Icon::from_rgba(pixels, width, height) else {return None};
return Some(icon);
}
2025/11/20
_winit_windows: Option<NonSend<bevy::winit::WinitWindows>>
を
_: bevy::ecs::system::NonSendMarker
に修正
まとめ
_: bevy::ecs::system::NonSendMarker
でメインスレッドを強制しないと
winit_windows
を取得できないみたいです。
クレジット
