我正在尝试使用GTK,Cairo和Glade在Rust中构建GUI。我想用gtk::DrawingArea
画一个运动场,但我不知道如何使用它。我有这个:
extern crate cairo;
extern crate gtk;
use gtk::*;
fn main() {
gtk::init().unwrap(); //init gtk before using it
let glade_src = include_str!("Glade_gui.glade"); //build the glade gui
let builder = gtk::Builder::new_from_string(glade_src);
//get widgets from the gui
let draw_area: gtk::DrawingArea = builder.get_object("zeichenbrett").unwrap();
let window: gtk::Window = builder.get_object("fenster").unwrap();
let size = (600, 600); //define the size for the image
let style_context: gtk::StyleContext = draw_area.get_style_context().unwrap(); //get the style context from the drawing area
let surface: cairo::ImageSurface =
cairo::ImageSurface::create(cairo::Format::ARgb32, size.0, size.1).unwrap(); //build a new ImageSurface to draw on
let context: cairo::Context = cairo::Context::new(&surface); //build a new cairo context from that ImageSurface to draw on
//just a blue area
context.set_source_rgb(0.0, 0.0, 1.0);
context.paint();
context.stroke();
gtk::functions::render_background(
&style_context,
&context,
0.0,
0.0,
size.0 as f64,
size.1 as f64,
); //here I thought that I drew the context cairo::Context to the drawingArea but it seems to do nothing.
window.show_all();
gtk::main();
}
它编译并运行,但窗口上没有显示任何运行环境。
我想我没有正确使用render_background
函数,但我不知道如何正确使用它。
下面是Glade_gui.glade文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="fenster">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Reise nach Jerusalem</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">5</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="links">
<property name="label" translatable="yes">Left</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="rechts">
<property name="label" translatable="yes">Right</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="quit">
<property name="label" translatable="yes">Quit</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="zeichenbrett">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
2条答案
按热度按时间roejwanj1#
需要注意的是,我没有Rust方面的经验,所以我将主要使用C示例。
您正在尝试在启动
gtk::main
之前呈现GUI。实现GTK+ GUI的正确方法是添加小部件,将它们的draw
信号(以及任何其他必要的信号)连接到您自己的draw回调函数,然后运行gtk::main
。作为示例,以这里找到的文档的简单GtkDrawingArea示例为例。在本例中,
g_signal_connect
用于将draw
信号连接到draw_callback
回调函数。这样,当gtk::main
实际创建小部件时,它将在其上绘制所需的图像。您的
draw_callback
函数将获取Cairo上下文作为参数。您将在该上下文上进行所有绘图,因此无需创建自己的上下文。这也在文档中通过在draw_callback
的参数中使用指针cr
来演示。所有的绘图都需要在
draw
回调函数中完成。它将在任何需要更新的时候被调用(包括创建GtkDrawingArea小部件),或者您可以通过发出queue_draw
信号来强制更新。即使在使用不同的语言时,C docs也能提供很大的帮助,特别是当您选择的语言没有全面的文档时。
此外,创建GTK+应用程序的推荐现代方法是使用GtkApplication。你可能想调查一下。
5fjcxozz2#
我不得不花了几个小时来找到一个解决方案与gtk-rs和GTK 4,因为有很少的例子。在GTK 4中,绘图函数必须注册到
gtk_drawing_area_set_draw_func
,而不是连接绘图信号。使用Rust绑定,我们需要使用DrawingAreaExtManual::set_draw_func
来设置draw函数。在我的例子中,我正在子类化DrawingArea,它给出了类似于这样的内容: