Manuel Utilisateur · gtk3sermo
Version : 1.1.4
Date : Mai 2026
Licence : GPL-2.0-or-later | Projet : haplo-dialog (devel@haplo-dialog.fr)
Table des matières
- Introduction
- Installation
- Premiers pas
- Syntaxe de base
- Référence des widgets
- Actions et signaux
- Variables et entrées/sorties
- Exemples pratiques
- Intégration dans un script shell
- FAQ et dépannage
1. Introduction
gtk3sermo est un utilitaire en ligne de commande qui permet de créer des fenêtres graphiques GTK 3 depuis n'importe quel script shell, Python, Perl ou autre langage interprété, sans écrire une seule ligne de code GTK.
Le principe est simple : vous décrivez votre interface en XML, et gtkdialog l'affiche. Quand l'utilisateur ferme la fenêtre, les valeurs saisies sont renvoyées sur la sortie standard sous forme de variables shell.
Exemple minimal :
export DIALOG='
<window title="Bienvenue">
<vbox>
<text><label>Entrez votre nom :</label></text>
<entry><variable>NOM</variable></entry>
<button><label>OK</label><action>EXIT:ok</action></button>
</vbox>
</window>'
gtkdialog --program=DIALOG
# Sortie : NOM="Jean" EXIT="ok"
1.1 Différences avec gtkdialog 0.8.3
gtk3sermo est 100% compatible avec les scripts écrits pour la version 0.8.3. Les seules différences visibles sont :
- L'apparence suit le thème GTK3 du système (plus moderne)
- Les couleurs sont spécifiées au format
rgba(r,g,b,a)ou#RRGGBB - Le terminal embarqué requiert VTE 2.91 (plus stable, meilleures performances)
2. Installation
2.1 Depuis les sources (recommandé)
# 1. Installer les dépendances
sudo apt-get install libgtk-3-dev libvte-2.91-dev \
flex bison autoconf automake pkg-config gcc
# 2. Compiler
cd gtk3sermo_1.1.4/
./autogen.sh
./configure
make -j$(nproc)
sudo make install
# 3. Vérifier
gtkdialog --version
2.2 Vérification de l'installation
echo '<window><vbox>
<text><label>gtk3sermo fonctionne !</label></text>
<button><label>Fermer</label><action>EXIT:ok</action></button>
</vbox></window>' | gtkdialog --stdin
Une fenêtre GTK doit apparaître. Si elle s'ouvre, l'installation est réussie.
2.3 Désinstallation
cd gtk3sermo_1.1.4/
sudo make uninstall
3. Premiers pas
3.1 Modes d'utilisation
gtkdialog accepte son XML de trois façons :
Depuis stdin :
echo '<window>...</window>' | gtkdialog --stdin
Depuis une variable d'environnement :
export MON_DIALOG='<window>...</window>'
gtkdialog --program=MON_DIALOG
Depuis un fichier :
gtkdialog --file=mon_interface.xml
3.2 Récupérer les valeurs saisies
Quand l'utilisateur ferme la fenêtre, gtkdialog affiche sur stdout les valeurs de tous les widgets nommés. Pour les utiliser dans votre script :
export DIALOG='
<window title="Formulaire">
<vbox>
<entry><variable>PRENOM</variable></entry>
<entry><variable>NOM_FAM</variable></entry>
<button><label>Valider</label><action>EXIT:valide</action></button>
<button><label>Annuler</label><action>EXIT:annule</action></button>
</vbox>
</window>'
# Évaluer la sortie pour créer les variables shell
eval $(gtkdialog --program=DIALOG)
if [ "$EXIT" = "valide" ]; then
echo "Bonjour $PRENOM $NOM_FAM !"
fi
4. Syntaxe de base
4.1 Structure d'un document gtkdialog
<window title="Titre de la fenêtre" resizable="true" width="400" height="300">
<vbox>
<!-- Widgets ici -->
</vbox>
</window>
Tout document gtkdialog commence par <window>. Les widgets sont imbriqués dans des conteneurs (<vbox>, <hbox>, <frame>, <notebook>).
4.2 Attributs communs à tous les widgets
| Attribut | Valeurs | Description |
|---|---|---|
sensitive |
true / false |
Activer/désactiver le widget |
visible |
true / false |
Afficher/cacher le widget |
tooltip-text |
texte | Infobulle au survol |
width-request |
nombre | Largeur minimale en pixels |
height-request |
nombre | Hauteur minimale en pixels |
4.3 Balises de contenu communes
| Balise | Description |
|---|---|
<variable>NOM</variable> |
Nom de la variable exportée à la fermeture |
<label>texte</label> |
Étiquette affichée dans le widget |
<default>valeur</default> |
Valeur initiale du widget |
<input>commande</input> |
Commande shell dont la sortie alimente le widget |
<action>ACTION:arg</action> |
Action déclenchée par une interaction |
<sensitive>false</sensitive> |
Désactiver le widget au démarrage |
5. Référence des widgets
5.1 Conteneurs
<window> · Fenêtre principale
<window title="Mon Application" resizable="true" width="500" height="400">
<vbox>
<!-- contenu -->
</vbox>
</window>
Attributs spécifiques : title, resizable, width, height, decorated, icon-name
<vbox> et <hbox> · Boîtes de disposition
<vbox space-expand="true" space-fill="true">
<hbox homogeneous="false" spacing="5">
<!-- widgets côte à côte -->
</hbox>
</vbox>
<vbox> empile les widgets verticalement, <hbox> horizontalement.
Attributs : homogeneous (même taille), spacing (espace en pixels), space-expand, space-fill
<frame> · Cadre avec titre
<frame label="Options" label-xalign="0.0">
<vbox>
<!-- contenu du cadre -->
</vbox>
</frame>
<notebook> · Onglets
<notebook tab-labels="Onglet 1|Onglet 2">
<vbox><!-- contenu onglet 1 --></vbox>
<vbox><!-- contenu onglet 2 --></vbox>
</notebook>
<scrolledwindow> · Zone défilante
<scrolledwindow>
<tree>...</tree>
</scrolledwindow>
5.2 Widgets de saisie
<entry> · Champ texte monoligne
<entry>
<variable>TEXTE</variable>
<default>valeur initiale</default>
<action signal="activate">EXIT:ok</action>
</entry>
<edit> · Zone de texte multiligne
<edit>
<variable>CONTENU</variable>
<default>Ligne 1
Ligne 2</default>
<width-request>400</width-request>
<height-request>200</height-request>
</edit>
<spinbutton> · Sélecteur numérique
<spinbutton range-min="0" range-max="100" range-step="1" digits="0">
<variable>VALEUR</variable>
<default>50</default>
</spinbutton>
<hscale> / <vscale> · Curseur
<hscale range-min="0" range-max="255" range-step="1" draw-value="true">
<variable>LUMINOSITE</variable>
<default>128</default>
</hscale>
5.3 Widgets de sélection
<checkbox> · Case à cocher
<checkbox>
<label>Activer les notifications</label>
<variable>NOTIF</variable>
<default>true</default>
<action>REFRESH:AUTRE_WIDGET</action>
</checkbox>
La variable vaut true ou false.
<radiobutton> · Bouton radio (choix exclusif)
<vbox>
<radiobutton>
<label>Option A</label>
<variable>CHOIX_A</variable>
</radiobutton>
<radiobutton>
<label>Option B</label>
<variable>CHOIX_B</variable>
</radiobutton>
</vbox>
<comboboxtext> · Liste déroulante simple
<comboboxtext>
<variable>COULEUR</variable>
<item>Rouge</item>
<item>Vert</item>
<item>Bleu</item>
<default>Vert</default>
</comboboxtext>
<list> · Liste avec sélection
<list>
<variable>SELECTION</variable>
<item>Élément 1</item>
<item>Élément 2</item>
<item>Élément 3</item>
</list>
<tree> · Arbre/tableau multi-colonnes
<tree selection-mode="single" column-header-active="true">
<variable>LIGNE</variable>
<label>Nom|Taille|Date</label>
<input>ls -lh --time-style=short | awk 'NR>1{print $9"|"$5"|"$6" "$7}'</input>
</tree>
5.4 Boutons et actions
<button> · Bouton générique
<button>
<label>Cliquez ici</label>
<action>EXIT:clique</action>
</button>
Avec icône :
<button>
<input file stock="gtk-open"></input>
<label>Ouvrir</label>
<action>FILESELECT:FICHIER</action>
</button>
Boutons de dialogue standard
<hbox>
<okbutton/>
<cancelbutton/>
</hbox>
Ces boutons ont les labels et raccourcis clavier standard et génèrent EXIT=OK ou EXIT=Cancel.
<togglebutton> · Bouton à bascule
<togglebutton>
<label>Activer</label>
<variable>ETAT</variable>
<default>false</default>
<action>REFRESH:AUTRE</action>
</togglebutton>
5.5 Affichage
<text> · Étiquette de texte
<text use-markup="true">
<label><b>Texte en gras</b> et <i>italique</i></label>
</text>
<pixmap> · Image
<pixmap>
<input file>/chemin/vers/image.png</input>
<width-request>64</width-request>
<height-request>64</height-request>
</pixmap>
<progressbar> · Barre de progression
<progressbar>
<variable>PROGRESSION</variable>
<input>echo 0.75</input>
</progressbar>
La valeur attendue est entre 0.0 et 1.0.
<statusbar> · Barre de statut
<statusbar>
<variable>STATUT</variable>
<default>Prêt</default>
</statusbar>
5.6 Widgets spéciaux
<colorbutton> · Sélecteur de couleur
<colorbutton>
<variable>COULEUR_HEX</variable>
<default>#ff6600</default>
</colorbutton>
La variable exportée est au format #RRGGBB|alpha.
<fontbutton> · Sélecteur de police
<fontbutton>
<variable>POLICE</variable>
<default>Sans 12</default>
</fontbutton>
<terminal> · Terminal embarqué (nécessite VTE)
<terminal>
<variable>TERMINAL</variable>
<width-request>600</width-request>
<height-request>300</height-request>
<input>echo "ls -la" | bash</input>
</terminal>
<timer> · Minuterie
<timer milliseconds="1000" visible="false">
<variable>HORLOGE</variable>
<action>REFRESH:AFFICHAGE</action>
</timer>
Déclenche une action toutes les N millisecondes.
5.7 Menus
<menubar>
<menu>
<label>Fichier</label>
<menuitem>
<label>Ouvrir</label>
<action>FILESELECT:FICHIER</action>
</menuitem>
<menuitemseparator/>
<menuitem>
<label>Quitter</label>
<action>EXIT:quitte</action>
</menuitem>
</menu>
</menubar>
5.13 Nouveaux widgets GTK3 (1.0.0)
Les six widgets suivants ont été ajoutés dans la version 1.0.0. Ils sont natifs GTK3 et n'existent pas dans gtkdialog 0.8.x.
switch · Interrupteur on/off
<switch>
<variable>MON_SWITCH</variable>
<default>true</default>
<action>echo "État : $MON_SWITCH"</action>
</switch>
Variable : true quand activé, false sinon.
filechooser · Sélecteur de fichier/dossier
<filechooser>
<label>Choisir un fichier</label>
<variable>FICHIER</variable>
<default>/home/user</default>
<action>echo "Sélectionné : $FICHIER"</action>
</filechooser>
Pour sélectionner un dossier : <filechooser action="select-folder">.
Variable : chemin absolu du fichier/dossier sélectionné.
calendar · Sélecteur de date
<calendar>
<variable>DATE</variable>
<default>2026-05-21</default>
<action>echo "Date : $DATE"</action>
</calendar>
Variable : date au format ISO 8601 YYYY-MM-DD.
linkbutton · Bouton hyperlien
<linkbutton>
<label>Visiter haplo-dialog.fr</label>
<default>https://haplo-dialog.fr</default>
<variable>LIEN</variable>
</linkbutton>
GTK3 ouvre automatiquement l'URI dans le navigateur par défaut. Variable : l'URI courante du bouton.
searchentry · Champ de recherche
<searchentry>
<label>Rechercher...</label>
<variable>TERME</variable>
<action>grep "$TERME" /var/log/syslog | head -20</action>
</searchentry>
Affiche une icône loupe et un bouton effacer. Signal search-changed
se déclenche après chaque frappe (avec anti-rebond automatique).
Variable : texte saisi.
infobar · Barre de notification
<infobar>
<label>Opération réussie.</label>
<default>info</default>
<variable>STATUS</variable>
</infobar>
Types disponibles pour <default> : info (bleu), warning (jaune),
error (rouge), question, other. Le texte peut être mis à jour
dynamiquement via REFRESH:STATUS.
Variable : texte courant de la barre.
6. Actions et signaux
6.1 Actions disponibles
| Action | Syntaxe | Description |
|---|---|---|
EXIT |
EXIT:valeur |
Ferme la fenêtre, exporte EXIT=valeur |
CLOSE |
CLOSE:NOM_FENETRE |
Ferme une fenêtre par nom |
LAUNCH |
LAUNCH:NOM_FENETRE |
Ouvre une nouvelle fenêtre |
REFRESH |
REFRESH:NOM_WIDGET |
Relance l'<input> d'un widget |
SAVE |
SAVE:NOM_WIDGET |
Sauvegarde l'état d'un widget |
CLEAR |
CLEAR:NOM_WIDGET |
Vide le contenu d'un widget |
APPEND |
APPEND:NOM_WIDGET |
Ajoute du contenu à un widget |
FILESELECT |
FILESELECT:NOM_VAR |
Ouvre un sélecteur de fichier |
ENABLE |
ENABLE:NOM_WIDGET |
Active un widget désactivé |
DISABLE |
DISABLE:NOM_WIDGET |
Désactive un widget |
SHOW |
SHOW:NOM_WIDGET |
Rend un widget visible |
HIDE |
HIDE:NOM_WIDGET |
Cache un widget |
GRABFOCUS |
GRABFOCUS:NOM_WIDGET |
Donne le focus clavier |
PRESENTWINDOW |
PRESENTWINDOW:NOM |
Met la fenêtre au premier plan |
6.2 Signaux disponibles
Par défaut, <action> réagit au signal principal du widget (clic pour un bouton, etc.). Pour d'autres signaux :
<entry>
<action signal="activate">EXIT:ok</action> <!-- Touche Entrée -->
<action signal="changed">REFRESH:APERCU</action> <!-- À chaque frappe -->
</entry>
Signaux courants : activate, changed, clicked, toggled, value-changed, cursor-changed, select-row
6.3 Exécuter une commande shell
<button>
<label>Ouvrir le navigateur</label>
<action>xdg-open https://exemple.com</action>
</button>
Toute action non reconnue comme mot-clé ACTION est exécutée comme commande shell via safe_system().
6.4 Actions conditionnelles
<button>
<label>Action selon état</label>
<action condition="command_is_true(test $CASE = 1)">REFRESH:WIDGET_A</action>
<action condition="command_is_false(test $CASE = 1)">REFRESH:WIDGET_B</action>
</button>
7. Variables et entrées/sorties
7.1 Nommer un widget
<entry><variable>MA_VALEUR</variable></entry>
À la fermeture, gtkdialog émet sur stdout : MA_VALEUR="contenu saisi"
7.2 Alimenter un widget depuis une commande
<text>
<variable>DATE_HEURE</variable>
<input>date "+%H:%M:%S"</input>
</text>
La commande est relancée à chaque REFRESH:DATE_HEURE.
7.3 Alimenter depuis un fichier
<edit>
<input file>/etc/hostname</input>
</edit>
7.4 Inclusion d'un fichier de fonctions
gtkdialog --include=/chemin/fonctions.sh --program=DIALOG
Permet d'utiliser des fonctions shell définies dans fonctions.sh dans les attributs <input> et <action>.
8. Exemples pratiques
8.1 Boîte de confirmation
#!/bin/bash
CONFIRM='
<window title="Confirmer" resizable="false">
<vbox>
<text><label>Voulez-vous supprimer ce fichier ?</label></text>
<hbox>
<button><label>Oui</label><action>EXIT:oui</action></button>
<button><label>Non</label><action>EXIT:non</action></button>
</hbox>
</vbox>
</window>'
eval $(echo "$CONFIRM" | gtkdialog --stdin)
[ "$EXIT" = "oui" ] && rm "$FICHIER" && echo "Supprimé."
8.2 Sélecteur de fichier
#!/bin/bash
SELECTOR='
<window title="Choisir un fichier">
<vbox>
<entry>
<variable>FICHIER</variable>
<default>/home</default>
</entry>
<button>
<label>Parcourir...</label>
<action>FILESELECT:FICHIER</action>
</button>
<hbox><okbutton/><cancelbutton/></hbox>
</vbox>
</window>'
eval $(echo "$SELECTOR" | gtkdialog --stdin)
[ "$EXIT" = "OK" ] && echo "Fichier choisi : $FICHIER"
8.3 Formulaire complet avec validation
#!/bin/bash
export FORMULAIRE='
<window title="Nouveau profil" width="350">
<vbox>
<frame label="Informations">
<vbox>
<hbox>
<text><label>Prénom :</label></text>
<entry><variable>PRENOM</variable></entry>
</hbox>
<hbox>
<text><label>Âge :</label></text>
<spinbutton range-min="1" range-max="120">
<variable>AGE</variable><default>25</default>
</spinbutton>
</hbox>
<hbox>
<text><label>Pays :</label></text>
<comboboxtext>
<variable>PAYS</variable>
<item>France</item><item>Belgique</item><item>Suisse</item>
</comboboxtext>
</hbox>
</vbox>
</frame>
<hbox><okbutton/><cancelbutton/></hbox>
</vbox>
</window>'
eval $(gtkdialog --program=FORMULAIRE)
if [ "$EXIT" = "OK" ]; then
echo "Profil créé : $PRENOM, $AGE ans, $PAYS"
fi
8.4 Moniteur de processus en temps réel
#!/bin/bash
export MONITEUR='
<window title="Processus actifs" width="600" height="400">
<vbox>
<tree column-header-active="true">
<variable>PROC</variable>
<label>PID|Utilisateur|CPU%|Commande</label>
<input>ps aux --no-headers | awk '"'"'{print $2"|"$1"|"$3"|"$11}'"'"' | head -20</input>
</tree>
<hbox>
<button>
<label>Rafraîchir</label>
<action>REFRESH:PROC</action>
</button>
<button><label>Fermer</label><action>EXIT:ok</action></button>
</hbox>
</vbox>
</window>'
gtkdialog --program=MONITEUR
8.5 Interface avec onglets
#!/bin/bash
ONGLETS='
<window title="Configuration" width="400">
<vbox>
<notebook tab-labels="Général|Réseau|Avancé">
<vbox>
<text><label>Paramètres généraux</label></text>
<entry><variable>NOM_HOST</variable><input>hostname</input></entry>
</vbox>
<vbox>
<text><label>Configuration réseau</label></text>
<entry><variable>IP_ADDR</variable><input>hostname -I | awk '"'"'{print $1}'"'"'</input></entry>
</vbox>
<vbox>
<text><label>Options avancées</label></text>
<checkbox><label>Mode débogage</label><variable>DEBUG</variable></checkbox>
</vbox>
</notebook>
<hbox><okbutton/><cancelbutton/></hbox>
</vbox>
</window>'
eval $(echo "$ONGLETS" | gtkdialog --stdin)
9. Intégration dans un script shell
9.1 Modèle de script complet
#!/bin/bash
# mon_app.sh - Application gtk3sermo
# Fonctions métier
charger_config() {
cat ~/.mon_app/config 2>/dev/null || echo "Aucune config"
}
sauvegarder_config() {
mkdir -p ~/.mon_app
echo "$1" > ~/.mon_app/config
}
# Interface
export INTERFACE='
<window title="Mon Application">
<vbox>
<edit>
<variable>CONFIG</variable>
<input>charger_config</input>
</edit>
<hbox>
<button>
<label>Sauvegarder</label>
<action>EXIT:sauvegarder</action>
</button>
<cancelbutton/>
</hbox>
</vbox>
</window>'
# Lancement avec accès aux fonctions
eval $(gtkdialog --include="$0" --program=INTERFACE)
# Traitement
case "$EXIT" in
sauvegarder) sauvegarder_config "$CONFIG" ; echo "Sauvegardé." ;;
*) echo "Annulé." ;;
esac
9.2 Fenêtres multiples
#!/bin/bash
export FENETRE_PRINCIPALE='
<window title="Principal" name="PRINCIPALE">
<vbox>
<button>
<label>Ouvrir paramètres</label>
<action>LAUNCH:PARAMETRES</action>
</button>
<button><label>Quitter</label><action>EXIT:quitte</action></button>
</vbox>
</window>
<window title="Paramètres" name="PARAMETRES" visible="false">
<vbox>
<text><label>Fenêtre de paramètres</label></text>
<button><label>Fermer</label><action>CLOSE:PARAMETRES</action></button>
</vbox>
</window>'
gtkdialog --program=FENETRE_PRINCIPALE
10. FAQ et dépannage
Q : La fenêtre ne s'affiche pas, j'obtiens une erreur Cannot open display
R : Vous êtes probablement en session SSH sans transmission X11 ou Wayland. Lancez export DISPLAY=:0 ou utilisez ssh -X.
Q : Mon script fonctionnait avec gtkdialog 0.8.3 mais plus maintenant
R : Vérifiez que vos attributs de couleur utilisent #RRGGBB et non les noms GTK2 (GdkColor). Le comportement fonctionnel est identique.
Q : Le widget <terminal> ne s'affiche pas
R : Le terminal nécessite libvte-2.91. Vérifiez : pkg-config --modversion vte-2.91. Si absent, installez libvte-2.91-0.
Q : Comment passer des données volumineuses à un widget <edit> ?
R : Utilisez <input file>/chemin/fichier</input> plutôt qu'une commande shell, c'est plus efficace pour les fichiers > 1 Mo.
Q : Ma commande <input> contient des guillemets et ne fonctionne pas
R : Échappez les guillemets simples : '"'"' dans bash, ou utilisez un fichier de fonctions avec --include.
Q : Comment afficher une barre de progression animée pendant une tâche longue ?
R : Utilisez un <timer> qui actualise la <progressbar> via REFRESH, et lancez votre tâche en arrière-plan en écrivant la progression dans un fichier temporaire.
Q : Puis-je utiliser gtk3sermo en Python ?
R : Oui. Construisez la chaîne XML en Python et passez-la via subprocess.run(['gtkdialog', '--stdin'], input=xml_str).
Q : Comment déboguer une interface qui ne se comporte pas comme prévu ?
R : Lancez avec gtkdialog --debug --program=VAR pour activer les messages de diagnostic. Redirigez stderr : gtkdialog --program=VAR 2>debug.log.