Rust 在窗口中绘制和更新

标签 rust graphics gtk cairo

我对 Rust 很陌生,很少做任何类型的图形或 UI 工作,所以预计会出现愚蠢的错误。

我正在尝试创建一个程序来运行模拟并显示其随时间变化的状态。为此,我想创建一个窗口,然后在其上绘制内容,并更改绘制的内容。理想情况下,如果它针对放置单个像素进行了优化(期望大多数时候每个时间步只有几个像素会发生变化),那就太好了,但现在我将满足于任何可以运行一些代码的地方,显示结果,运行更多代码,然后刷新显示。

到目前为止我所拥有的:

fn main() {
let app = Application::builder()
    .application_id("org.example.HelloWorld")
    .build();

app.connect_activate(|app| {
    let win = ApplicationWindow::builder()
        .application(app)
        .default_width(320)
        .default_height(200)
        .title("Hello, World!")
        .build();

    let draw_area = DrawingArea::new();
    win.add(&draw_area);
    draw_area.connect_draw(|_unused, f| {
        f.set_source_rgb(1.0, 0.0, 0.0);
        f.paint();
        thread::sleep(time::Duration::from_millis(1000));
        f.set_source_rgb(0.0, 1.0, 0.0);
        f.paint();
        Inhibit(false)
    });
    win.show_all();
});
app.run();
}

我希望显示一个全红色的窗口,等待一秒钟,然后显示一个全绿色的窗口。相反,它会等待一秒钟并显示一个全绿色的窗口。我如何重组它,以便我可以按我控制的时间间隔更新显示?

最佳答案

我不知道 GTK,但大多数 GUI 系统都有一些相当常见的属性,所以我会给你一个通用的答案,因为还没有其他人这样做:

只要您希望“时间正常流逝”,您就需要将控制权返回给事件循环。也就是说,永远不要使用thread::sleep;如果您想稍后执行某些操作,请使用事件循环的计时器机制,稍后将调用回调。 (我找不到 gtk 箱中的其中一个,但我几乎肯定它会的。)

此外,您还需要考虑,您的 draw 回调可能会在调整窗口大小时被调用,以实现完全重绘。 GUI 很少提供“保留”小部件来记住在调整大小事件中应显示哪些像素;通常,如果您愿意,您需要自己的图像缓冲区来执行此操作,并且对于大多数动画目的,传统的做法是在您希望更改时重新绘制所有内容。如果您的应用程序正在缓慢地放置特定像素,您可能应该保留自己的图像缓冲区。

关于Rust 在窗口中绘制和更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71633131/

相关文章:

memory-management - 有没有办法为大型 Rust 分配预填充操作系统的页表?

optimization - Rust 会优化计算范围内的循环吗?

c# - XNA 二维绘图库

graphics - 了解图形和成像的最佳资源?

string - 在 Rust 中检查字符串是否以某个字符开头的正确和惯用方法是什么?

rust - 如何在不冒犯借用检查器的情况下进行计算状态转换?

c - 用多边形算法中的点填充C中的多边形

c# - 在 Gtk# 中,如何在拖放中传递对象引用?

编译 64 位 Linux 的 32 位 GTK+ 应用程序

c++ - 从 gtk treeview 的选定行获取数据 - gtkmm,c++