Gnome: Desarrollo de aplicaciones. Menús y acciones
Cuarto artículo de la serie de Desarrollo de aplicaciones en GNOME/Vala: añade una AdwHeaderBar con menú a tu ventana GTK4/libadwaita y conecta la opción About a un SimpleAction que abre un Adw.AboutDialog.
Gnome: Desarrollo de aplicaciones. La aplicación
En el artículo anterior creamos nuestra aplicación core. Una aplicación simple que solo abre una ventana si más que un mensaje de texto en su centro. En este articulo vamos a abordar cómo añadir la barra superior de la ventana con las acciones de cierre, ventana completa, minimizar y menú.
Hasta ahora tenemos esta template para nuestra ventana principal:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ExampleMainWindow" parent="AdwApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Hello</property>
</object>
</child>
</template>
</interface>Para empezar vamos a incluir las dependencias que queremos usar en nuestra interfaz:
...
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.0"/>
...
</interface> Las opciones de menú que vamos a usar:
...
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.0"/>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">About Example</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
...
</interface> Añadimos la toolbar de la ventana:
...
<property name="default-height">400</property>
<child>
<object class="AdwToastOverlay" id="toast_overlay">
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title">Example</property>
</object>
</property>
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="tooltip-text" translatable="yes">Main Menu</property>
<property name="menu-model">primary_menu</property>
<property name="primary">true</property>
<style><class name="flat"/></style>
</object>
</child>
</object>
</child>
...
</object>
</property>
</object>
</child>El resultado final debe visualizarse de esta forma:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.0"/>
<menu id="primary_menu">
<section>
<item>
<attribute name="label" translatable="yes">About Example</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<template class="ExampleMainWindow" parent="AdwApplicationWindow">
<property name="title" translatable="yes">Example Application</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child>
<object class="AdwToastOverlay" id="toast_overlay">
<property name="child">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<property name="title-widget">
<object class="AdwWindowTitle">
<property name="title">Example</property>
</object>
</property>
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="tooltip-text" translatable="yes">Main Menu</property>
<property name="menu-model">primary_menu</property>
<property name="primary">true</property>
<style><class name="flat"/></style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Hello</property>
</object>
</child>
</object>
</property>
</object>
</child>
</template>
</interface>Nuestra ventana ahora se debe visualizar de esta forma:

¿Qué es lo que vamos a hacer ahora? Vamos a meter el handler para el action definido para nuestro menú. Esta acción abrirá un modal con la información de la aplicación. Por suerte, o no, adw ya dispone de un widget que realiza todo esto y solo tenemos que darle los parámetros que queramos mostrar.
Como siempre, para este tipo de aplicaciones nos vamos a encontrar que podríamos abordar esto de varias formas, pero por ahora vamos a ver cuál es la forma más directa de realizar esto.
SimpleAction es parte de las Glib (gio) y es la forma más sencilla de añadir acciones a nuestros menús, otra opción podría ser usar conectores que podemos ver más adelante pero por ahora y para el propósito de nuestro ejemplo es una buena opción empezar con SimpleAction.
src/application.vala
construct
{
var about_action = new SimpleAction ("about", null);
about_action.activate.connect (showAbout);
add_action (about_action);
}Entre otras acciones también podemos añadir una combinación de teclas para lanzar la acción:
construct
{
var about_action = new SimpleAction ("about", null);
about_action.activate.connect (showAbout);
add_action (about_action);
set_accels_for_action ("app.about", { "<Ctrl>A" });
}Por último añadimos el method al que va a llamar la acción y abrir el dialog:
En valadoc podemos ver todas las propiedades y métodos de estos widgets
private void showAbout ()
{
var dialog = new Adw.AboutDialog ();
dialog.application_name = "Example";
dialog.application_icon = "io.github.agustingv.example";
dialog.version = "1.0.0";
dialog.developer_name = "Example Contributors";
dialog.license_type = Gtk.License.GPL_3_0;
dialog.website = "https://github.com/agustingv/example";
dialog.issue_url = "https://github.com/agustingv/example/issues";
dialog.comments = _("A simple example application");
dialog.present (active_window);
}Nuestro código final debe quedar de forma similar a esta:
namespace Example
{
public class Application : Adw.Application
{
public Application ()
{
Object (
application_id: "io.github.agustingv.example",
flags: ApplicationFlags.DEFAULT_FLAGS
);
}
construct
{
var about_action = new SimpleAction ("about", null);
about_action.activate.connect (showAbout);
add_action (about_action);
set_accels_for_action ("app.about", { "<Ctrl>A" });
}
protected override void activate ()
{
var win = this.active_window;
if (win == null) {
win = new Example.MainWindow (this);
}
win.present ();
}
private void showAbout ()
{
var dialog = new Adw.AboutDialog ();
dialog.application_name = "Example";
dialog.application_icon = "io.github.agustingv.example";
dialog.version = "1.0.0";
dialog.developer_name = "Example Contributors";
dialog.license_type = Gtk.License.GPL_3_0;
dialog.website = "https://github.com/agustingv/example";
dialog.issue_url = "https://github.com/agustingv/example/issues";
dialog.comments = _("A simple example application");
dialog.present (active_window);
}
}
}
Gnome: Desarrollo de aplicaciones. Construyendo una nueva aplicación
Artículos recientes
Artículo
Gnome: Desarrollo de aplicaciones. Pango
04/09/2026
Artículo
Gnome: Desarrollo de aplicaciones. VAPI
03/09/2026
Artículo
Gnome: Desarrollo de aplicaciones. MVVM
15/08/2026
Artículo
Gnome: Desarrollo de aplicaciones. Construyendo una nueva aplicación
10/08/2026
Artículo
Linux: Guía de iniciación a Linux
08/08/2026
Noticia
Wayland
08/08/2026