Prerequisites

Before we start, ensure you have the following installed on your system:

  • Rust (latest stable version)
  • cargo (comes with Rust)
  • GTK development libraries

You can install GTK on Linux using your package manager. For example, on Ubuntu, run:

sudo apt install libgtk-3-dev

For Windows, you can use MSYS2 to install GTK. On macOS, you can use Homebrew:

brew install gtk+3

Setting Up Your Rust Project

First, create a new Rust project using Cargo:

cargo new rust_gtk_app
cd rust_gtk_app

Next, add the GTK dependency to your Cargo.toml file:

[dependencies]
gtk = "0.9"
glib = "0.9"

Writing the Application

Now, open src/main.rs and replace its contents with the following code:

extern crate gtk;
use gtk::prelude::*;
use gtk::{Button, Label, Window, WindowType};

fn main() {
    // Initialize GTK before proceeding
    gtk::init().expect("Failed to initialize GTK.");

    // Create a new top-level window
    let window = Window::new(WindowType::Toplevel);
    window.set_title("Simple GTK App");
    window.set_default_size(300, 100);

    // Create a label and a button
    let label = Label::new(Some("Hello, GTK!"));
    let button = Button::with_label("Click Me!");

    // Set up the button click event
    button.connect_clicked(move |_| {
        label.set_text("Button Clicked!");
    });

    // Create a vertical box to hold the label and button
    let vbox = gtk::Box::new(gtk::Orientation::Vertical, 5);
    vbox.pack_start(&label, true, true, 0);
    vbox.pack_start(&button, true, true, 0);

    // Add the box to the window
    window.add(&vbox);

    // Connect the window's close event
    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    // Show all widgets
    window.show_all();

    // Start the GTK main loop
    gtk::main();
}

Code Breakdown

  1. Importing GTK: The gtk::prelude::* allows us to use GTK traits without prefixing them with gtk::.
  1. Initializing GTK: The gtk::init() function initializes the GTK library. It must be called before any GTK functions are used.
  1. Creating a Window: We create a new window of type Toplevel, set its title, and define its default size.
  1. Creating Widgets: A Label and a Button are created. The button is connected to a click event that changes the label's text.
  1. Layout Management: We use a vertical box (gtk::Box) to arrange the label and button vertically.
  1. Event Handling: The window's delete event is connected to gtk::main_quit(), which exits the application when the window is closed.
  1. Running the Application: Finally, gtk::main() starts the GTK main loop, allowing the application to respond to events.

Building and Running the Application

To build and run your application, use the following command:

cargo run

You should see a window with a label and a button. Clicking the button will change the label's text.

Summary of Key Concepts

ConceptDescription
GTK InitializationUse gtk::init() to initialize the GTK library.
Window CreationCreate a window using Window::new(WindowType::Toplevel).
Widget CreationUse widgets like Label and Button for user interface elements.
Event HandlingConnect events using the connect_clicked method for buttons.
Layout ManagementUse containers like gtk::Box to arrange widgets.
Main LoopCall gtk::main() to start the event loop.

Best Practices

  • Error Handling: Always handle errors when initializing GTK and performing UI actions.
  • Modular Code: Consider separating your application logic into modules for better organization.
  • Responsive Design: Use layout containers effectively to ensure your application looks good on different screen sizes.

Conclusion

In this tutorial, we created a simple GUI application using Rust and GTK. You learned how to set up your project, create a window, add widgets, and handle user interactions. With this foundation, you can explore more complex features of GTK and build more sophisticated applications.

Learn more with useful resources: