控件

控件(Widget)是组成 GTK 应用程序的组件。 GTK 提供了许多控件,如果这些控件不合适,您甚至可以自定义。 例如,控件包含了显示控件、按钮、容器和窗口。 一种控件可能能够包含其他控件,它可能会用于展示信息,并且可能会对交互做出反应。

Widget Gallery 有助于找出适合你的需求的控件。 假设我们想向应用程序添加一个按钮。 我们这里有很多选择,但让我们以最简单的一个——Button

GTK 是一个面向对象的框架,因此所有控件都是继承树的一部分,顶部是 GObject. 继承树如下所示:

GObject
╰── Widget
    ╰── Button

GTK 文档还告诉我们,Button实现了 GtkAccessible, GtkActionable, GtkBuildable, GtkConstraintTarget 接口。

现在让我们将其与 gtk-rs 中的 Button 结构进行比较。 gtk-rs 文档告诉我们它实现了哪些 trait。 我们发现这些 trait 在 GTK 文档中要么有相应的基类,要么有接口。 在 “Hello World” 程序中,我们希望对按钮单击做出反应。 这种行为是按钮特有的,因此我们希望在 ButtonExt trait 中找到合适的方法。 而事实上,ButtonExt 包含了 connect_clicked 方法。

文件名:listings/hello_world/3/main.rs

use gtk::prelude::*;
use gtk::{glib, Application, ApplicationWindow, Button};
const APP_ID: &str = "org.gtk_rs.HelloWorld3";

fn main() -> glib::ExitCode {
    // Create a new application
    let app = Application::builder().application_id(APP_ID).build();

    // Connect to "activate" signal of `app`
    app.connect_activate(build_ui);

    // Run the application
    app.run()
}

fn build_ui(app: &Application) {
    // Create a button with label and margins
    let button = Button::builder()
        .label("Press me!")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    // Connect to "clicked" signal of `button`
    button.connect_clicked(|button| {
        // Set the label to "Hello World!" after the button has been clicked on
        button.set_label("Hello World!");
    });

    // Create a window
    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK App")
        .child(&button)
        .build();

    // Present window
    window.present();
}