Zoeken…


[C ++] met behulp van Gtk :: Builder in gtkmm

Overzicht

Gtk + ondersteunt een workflow waarbij de taak van het ontwerp van de gebruikersinterface en de programmering worden ontkoppeld. Hoewel de elementen van de gebruikersinterface zoals knoppen, menu's, lay-out enz. Rechtstreeks vanuit code kunnen worden toegevoegd, maakt deze aanpak niet alleen de code rommelig, maar maakt het ook het wijzigen van de gebruikersinterface voor iedereen moeilijk, maar voor de programmeur. Bovendien worden sommige interface-elementen alleen gebruikt om de lay-outstructuur te behouden en hoeven ze niet aan logica deel te nemen, ze toe te voegen vanuit code maakt het alleen maar langer. In plaats daarvan kan Glade worden gebruikt om de UI-beschrijving te genereren, aangezien XML en Gtk + Builder API kunnen worden gebruikt om de UI te laden en erop te werken.

workflow

  1. Ontwerp UI-elementen in Glade met slepen en neerzetten. Glade genereert een XML-bestand dat UI-beschrijvingen bevat. Dit kan ook handmatig worden gedaan door de juiste XML-syntaxis te schrijven en op te slaan met een .glade extensie.
  2. Laad UI rechtstreeks uit het bestand met
    auto ui = Gtk::Builder::create_from_file("ui.glade");
    
  3. Toegang tot individuele UI-elementen
    // when element doesn't need to be added to another UI element
    auto ui_elem = Glib::RefPtr<Gtk::Button>::cast_dynamic(
        ui->get_object("button_UI_id")
    );
    // when element needs to be added to another widget
    Gtk::Button *btn = nullptr;
    ui->get_widget<Gtk::Button>("button_UI_id", btn);
    

Voorbeeld

Glade UI

Voorbeeld UI: simple.glade

simple.glade

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkBox" id="cont">
    <property name="width_request">200</property>
    <property name="height_request">200</property>
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="orientation">vertical</property>
    <child>
      <object class="GtkLabel" id="display_label">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="wrap">True</property>
        <attributes>
          <attribute name="weight" value="bold"/>
          <attribute name="scale" value="5"/>
          <attribute name="foreground" value="#a4a400000000"/>
        </attributes>
      </object>
      <packing>
        <property name="expand">True</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkButton" id="display_button">
        <property name="label" translatable="yes">Display Message</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>
  </object>
</interface>

simple.cpp

#include <gtkmm/application.h>
#include <gtkmm/applicationwindow.h>
#include <gtkmm/button.h>
#include <gtkmm/label.h>
#include <gtkmm/box.h>
#include <gtkmm/builder.h>

class HelloWindow : public Gtk::ApplicationWindow {
    Gtk::Box *cont;
    Glib::RefPtr<Gtk::Label> display_label;
    Glib::RefPtr<Gtk::Button> display_btn;
    Glib::RefPtr<Gtk::Builder> ui;
public:
    HelloWindow()
    : ui{Gtk::Builder::create_from_file("simple.glade")} {
        if(ui) {
            ui->get_widget<Gtk::Box>("cont", cont);
            display_label = Glib::RefPtr<Gtk::Label>::cast_dynamic(
                ui->get_object("display_label")
            );
            display_btn = Glib::RefPtr<Gtk::Button>::cast_dynamic(
                ui->get_object("display_button")
            );
            if(cont && display_label && display_btn) {
                display_btn->signal_clicked().connect(
                [this]() {
                    display_label->set_text("Hello World");
                });
                add(*cont);
            }
        }
        set_title("Simple Gtk::Builder demo");
        set_default_size(400, 400);
        show_all();
    }
};

int main(int argc, char *argv[]) {
    auto app = Gtk::Application::create(
        argc, argv, 
        "org.gtkmm.example.HelloApp"
    );
    HelloWindow hw;
    return app->run(hw);
}

uitgang

uitgang

Gio gebruiken :: Bron

UI's rechtstreeks vanuit .glade bestanden laden is snel en eenvoudig. Maar wanneer de applicatie is verpakt, kunnen UI-beschrijvingen, pictogrammen en andere afbeeldingen worden samengevoegd in resourcebundels . Eerst moet een bronbeschrijving worden aangemaakt als XML-bestand.

resources.xml

<gresources>
    <gresource prefix="/unique/prefix/">
        <file>icon.png</file>
        <!-- text files such as XML can be compressed to save memory -->
        <file compressed="true">ui.glade</file>
    </gresource>
</gresources>

Maak vervolgens een afzonderlijk .gresource bestand of een .c bestand met bronnen als tekenreeksgegevens die moeten worden gekoppeld als onderdeel van de toepassing.

# generates separate resource file
glib-compile-resources --target=ui.gresource resources.xml
# generates .c file
glib-compile-resources --generate-source resources.xml

Laad vervolgens vanuit de toepassingscode de bronbundel

// from separate file
auto resource_bundle = Gio::Resource::create_from_file("ui.gresource");
// from stream of bytes in .c file
auto resource_bundle = Glib:wrap(draw_resource_get_resource());
resource_bundle.register_global();

Van resourcebundel laad UI-elementen

auto ui = Gtk::Builder::create_from_resource("/unique/prefix/ui.glade");


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow