我对 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/