Поиск…


[C ++] с использованием Gtk :: Builder в gtkmm

обзор

Gtk + поддерживает рабочий процесс, где задача дизайна пользовательского интерфейса и задачи программирования развязаны. Хотя элементы пользовательского интерфейса, такие как кнопки, меню, макет и т. Д., Могут быть непосредственно добавлены из кода, этот подход не только загромождает код, но и изменяет пользовательский интерфейс для любого, кроме программиста. Кроме того, некоторые элементы интерфейса используются только для хранения структуры макета и не должны участвовать в логике, добавив их из кода, только делает его более длинным. Вместо этого Glade может использоваться для генерации описания пользовательского интерфейса, поскольку XML и Gtk + Builder API могут использоваться для загрузки пользовательского интерфейса и работы с ним.

Workflow

  1. Создайте элементы пользовательского интерфейса в Glade, используя перетаскивание. Glade генерирует XML-файл, содержащий описания пользовательского интерфейса. Это также можно сделать вручную, написав правильный синтаксис XML и сохранив его с расширением .glade .
  2. Загрузите пользовательский интерфейс из файла напрямую
    auto ui = Gtk::Builder::create_from_file("ui.glade");
    
  3. Доступ к отдельным элементам пользовательского интерфейса
    // 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);
    

пример

Пользовательский интерфейс Glade

Пример 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);
}

Выход

выход

Использование Gio :: Ресурс

Загрузка пользовательских интерфейсов непосредственно из файлов .glade выполняется быстро и просто. Но когда приложение упаковано, описания пользовательского интерфейса, значки и другие изображения могут быть объединены в пакеты ресурсов . Сначала описание ресурса должно быть создано как XML-файл.

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>

Затем либо создайте отдельный файл .gresource либо файл .c содержащий ресурсы, в качестве строковых данных, которые должны быть связаны как часть приложения.

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

Затем из кода приложения загрузите пакет ресурсов

// 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();

Из элементов пользовательского интерфейса загрузки пакетов ресурсов

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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow