【rust/egui】(二)看看template的main函数:日志输出以及eframe run_native

说在前面

  • rust新手,egui没啥找到啥教程,这里自己记录下学习过程
  • 环境:windows11 22H2
  • rust版本:rustc 1.71.1
  • egui版本:0.22.0
  • eframe版本:0.22.0
  • 上一篇:这里

开始

  • 首先让我们看看main.rs中有些什么
    #![warn(clippy::all, rust_2018_idioms)]
    #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] 
    // 在release模式中隐藏控制台窗口(实际上我怎么试也没找到这个窗口) 本文放弃关注
    
    // 非wasm架构
    #[cfg(not(target_arch = "wasm32"))]
    fn main() -> eframe::Result<()> {
        env_logger::init(); // 初始化log参数,debug模式下仅会打印error日志
    
        let native_options = eframe::NativeOptions::default(); // 初始化eframe默认参数
        eframe::run_native(
            "demo app",
            native_options,
            Box::new(|cc| Box::new(demo_app::TemplateApp::new(cc))),
        )
        // 启动eframe
    }
    
    // When compiling to web using trunk:
    #[cfg(target_arch = "wasm32")]
    // ... 本文暂不关注wasm相关内容
    

日志输出

  • eframe中使用的日志库为log以及env_logger,其日志等级有5个:
    pub enum Level {
        Error,
        Warn,
        Info,
        Debug,
        Trace,
    }
    
  • 我们可以在main函数中添加测试一下:
    fn main() -> eframe::Result<()> {
        env_logger::init(); 
        // Log to stderr (if you run with `RUST_LOG=debug`).
    
        log::info!("1");
        log::warn!("2");
        log::error!("3");
        log::trace!("4");
        log::debug!("5");
    
        // ...
    }
    
  • 执行cargo run,只能看到error输出;使用cargo run --release的话什么日志都没有了
    [2023-08-13T09:20:59Z ERROR demo_app] 3
    
  • env_logger可以指定日志输出的级别以及目标,当我们在cmd下执行(注意powershell的设置环境变量的语法不一样):
    set RUST_LOG=demo_app
    cargo run
    
    这会将我们的项目(demo_app)下所有的级别的log进行输出,现在我们能看到所有级别的日志了
    [2023-08-13T09:27:18Z INFO  demo_app] 1
    [2023-08-13T09:27:18Z WARN  demo_app] 2
    [2023-08-13T09:27:18Z ERROR demo_app] 3
    [2023-08-13T09:27:18Z TRACE demo_app] 4
    [2023-08-13T09:27:18Z DEBUG demo_app] 5
    
  • 现在我们尝试下将eframe的日志都输出:
    set RUST_LOG=eframe
    cargo run
    
    可以看到大量的日志输出:
    [2023-08-13T09:31:29Z DEBUG eframe] Using the glow renderer
    [2023-08-13T09:31:29Z DEBUG eframe::native::run] Entering the winit event loop (run_return)

eframe初始化参数

  • 在main函数中调用eframe::run_native()时使用到了一个native_options,让我们看看这里面有些什么:

    always_on_top: bool
    Sets whether or not the window will always be on top of other windows at initialization.
    
    maximized: bool
    Show window in maximized mode
    
    decorated: bool
    On desktop: add window decorations (i.e. a frame around your app)? 
    If false it will be difficult to move and resize the app.
    
    fullscreen: bool
    Start in (borderless) fullscreen?
    
    ...
    
  • 我们可以试着改几个看看效果

    • always_on_top
      let mut native_options = eframe::NativeOptions::default();
      native_options.always_on_top = true;
      
      在这里插入图片描述
    • decorated
      let mut native_options = eframe::NativeOptions::default();
          native_options.always_on_top = true;
          native_options.decorated = false;
      
      在这里插入图片描述
      毫无灵魂了,甚至和背景融为一体了
    • transparent
      let mut native_options = eframe::NativeOptions::default();
          native_options.transparent = true;
      // 同时注释掉app.rs中 egui::CentralPanel::default() 代码
      
      在这里插入图片描述
  • 其他详细参数见这里,大家可以自己试试

eframe::run_native

  • 调用该函数创建我们的应用窗口,其定义为:
    pub fn run_native(
        app_name: &str, // 应用名
        native_options: NativeOptions, // 初始化选项
        app_creator: AppCreator // 应用主逻辑
    ) -> Result<()>
    
  • app_name
    应用名称,在我们的例子中为demo app;同时该值也是我们的窗口显示的名称,同时也是持久化存储(下一节看看 )目录的名称;
    在这里插入图片描述
    在这里插入图片描述

相关参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 使用以下代码: let socket_addr: std::net::SocketAddr = // ...; let win_socket_addr: windows_sys::Win32::Networking::WinSock::SOCKADDR_IN = socket_addr.into(); ### 回答2: 要将std::net::SocketAddr转化为windows_sys::Win32::Networking::WinSock::SOCKADDR_IN,可以使用以下Rust代码: ```rust use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use winapi::um::winsock2::SOCKADDR_IN; use winapi::shared::ws2def::{AF_INET, AF_INET6}; use winapi::shared::in6addr::in6addr_any; fn socket_addr_to_sockaddr_in(socket_addr: &SocketAddr) -> SOCKADDR_IN { let ip_addr = socket_addr.ip(); let port = socket_addr.port(); match ip_addr { IpAddr::V4(ipv4_addr) => { let mut sockaddr_in: SOCKADDR_IN = unsafe { std::mem::zeroed() }; sockaddr_in.sin_family = AF_INET as u16; sockaddr_in.sin_addr.S_un.S_addr = u32::from(ipv4_addr); sockaddr_in.sin_port = port.to_be(); sockaddr_in } IpAddr::V6(ipv6_addr) => { let mut sockaddr_in6: SOCKADDR_IN = unsafe { std::mem::zeroed() }; sockaddr_in6.sin6_family = AF_INET6 as u16; sockaddr_in6.sin6_port = port.to_be(); sockaddr_in6.sin6_addr = *ipv6_addr.segments(); if *ipv6_addr == Ipv6Addr::from(in6addr_any) { sockaddr_in6.sin6_addr = *in6addr_any; } sockaddr_in6 } } } fn main() { let socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); let sockaddr_in = socket_addr_to_sockaddr_in(&socket_addr); // Do something with the converted SOCKADDR_IN println!( "Converted SOCKADDR_IN: {{ family: {}, addr: {}, port: {} }}", sockaddr_in.sin_family, sockaddr_in.sin_addr.S_un.S_addr, sockaddr_in.sin_port ); } ``` 以上代码使用Rust的winapi库来访问Windows Socket API,并将std::net::SocketAddr的IP地址和端口转换为windows_sys::Win32::Networking::WinSock::SOCKADDR_IN结构体。根据输入的std::net::SocketAddr类型,使用IF_INET或IF_INET6来设置SOCKADDR_IN的family字段。然后将IP地址和端口填充到SOCKADDR_IN结构体中。在这个例子中,我们将std::net::SocketAddr转化为127.0.0.1:8080的SOCKADDR_IN。 ### 回答3: 使用Rust编写的代码如下所示: ```rust use std::net::SocketAddr; use windows_sys::Win32::Networking::WinSock::SOCKADDR_IN; fn main() { let socket_addr = SocketAddr::new("127.0.0.1".parse().unwrap(), 8080); let sockaddr_in = SOCKADDR_IN { sin_family: 2, // AF_INET sin_port: socket_addr.port().to_be(), sin_addr: socket_addr.ip().octets().into(), sin_zero: [0; 8], // initialize sin_zero with zeros }; println!("SOCKADDR_IN: {:?}", sockaddr_in); } ``` 以上代码首先导入了`std::net::SocketAddr`和`windows_sys::Win32::Networking::WinSock::SOCKADDR_IN`模块。然后创建了一个`SocketAddr`实例,该实例包含了IP地址和端口号。接下来,我们定义了一个`SOCKADDR_IN`结构体变量,并根据`SocketAddr`的信息进行初始化。最后,打印输出了转换后的`SOCKADDR_IN`实例。 这段代码将`std::net::SocketAddr`转化为了`windows_sys::Win32::Networking::WinSock::SOCKADDR_IN`。在转换过程中,我们将IP地址转化为字节数组,然后将端口号进行了字节序的转换。最后,我们打印输出了转换后的结果,以便验证转换是否成功。 注意:本示例中使用的`sockets` crate中的`windows-sys`模块提供了便于与Windows系统交互的Rust绑定,以简化开发过程。请在使用之前确认已在`Cargo.toml`中添加相应的依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值