The first article showed how to install GTK4 and associated libraries and developed a program to create a window containing button and label widgets. This article shows how to create an alarm clock application with a Graphical User Interface (GUI). A screenshot of the GTK4 alarm clock application that has been developed using Ubuntu 24.04 is shown below. In this application a label widget for displaying the time, spin buttons for setting the alarm time (hour and minute) and a minimise button are going to be used. A grid container for positioning the widgets will also be used. Coding The Alarm Clock The full source code for this project can be downloaded using the web link below: https://github.com/crispinprojects/fullcircle Open and view the main.c file to follow the explanation below.
Le premier article a montré comment installer GTK4 et les bibliothèques associées, et un programme pour créer une fenêtre contenant des widgets de boutons et d'étiquettes a été développé. Cet article explique comment créer une application de réveil avec une interface utilisateur graphique (GUI).
Une capture d'écran de l'application de réveil GTK4, développée sous Ubuntu 24.04, est présentée ci-dessous.
Cette application utilise un widget d'étiquette pour afficher l'heure, des boutons rotatifs pour régler l'heure de l'alarme (heures et minutes) et un bouton de réduction. Un conteneur de grille permet également de positionner les widgets.
Coder le réveil
Le code source complet de ce projet est téléchargeable via le lien Web ci-dessous : https://github.com/crispinprojects/fullcircle
Ouvrez et visualisez le fichier main.c pour suivre les explications ci-dessous.
Two static integer variables called m_alarm_hour and m_alarm_min are declared. These are used to store the hour and minute values for a specific alarm time. The alarm clock is going to play some audio beeps when the desired time is reached. In this context the static keyword means that the variables are not available outside the source code file (main.c in this case) and they retain their value between multiple function calls. A set of GtkWidget pointers are created in the activate() function for the widgets to be used in the application. These include the window, grid container, time label, the minimise button and two spin buttons for setting the alarm hour and minute values. A window is created using gtk_application_window_new() and the window title set to “Alarm Clock” and the default size to 400×150. Then the grid layout container is created which arranges its child widgets in rows and columns. The function gtk_grid_set_column_homogeneous() is used to set all columns of the grid to have the same width. A label called label_time is created which will display the current time value. Two dummy spacer labels called label_spacer1 and label_spacer2 are used to help with grid alignment.
Deux variables entières statiques, m_alarm_hour et m_alarm_min, sont déclarées. Elles servent à stocker les valeurs d'heure et de minutes d'une alarme spécifique. Le réveil émet des bips sonores lorsque l'heure souhaitée est atteinte. Dans ce contexte, le mot-clé static signifie que les variables ne sont pas disponibles en dehors du fichier source (main.c dans ce cas) et qu'elles conservent leur valeur entre plusieurs appels de fonction.
Un ensemble de pointeurs GtkWidget est créé dans la fonction activate() pour les widgets à utiliser dans l'application. Ceux-ci incluent la fenêtre, le conteneur de grille, l'étiquette horaire, le bouton de réduction et deux boutons rotatifs pour régler les valeurs de l'heure et des minutes de l'alarme.
Une fenêtre est créée à l'aide de la fonction gtk_application_window_new(), avec le titre « Réveil » et la taille par défaut à 400×150. Le conteneur de disposition de grille est ensuite créé, organisant ses widgets enfants en lignes et en colonnes. La fonction gtk_grid_set_column_homogeneous() permet de définir la même largeur pour toutes les colonnes de la grille. Une étiquette, intitulée label_time, est créée pour afficher l'heure actuelle. Deux étiquettes d'espacement factices, label_spacer1 et label_spacer2, facilitent l'alignement de la grille.
Two GtkAdjustment objects called adjustment_alarm_hour and adjustment_alarm_min are created. Adjustments are used by GtkSpinButton widgets to set the lower and upper bounds of step increments. The online GTK4 Application Programming Interface (API) documentation shows that the gtk_adjustment_new() constructor for creating a new GtkAdjustment takes the following parameter values: the initial value, minimum value, maximum value, step increment, page increment and page size. The GtkSpinButton widgets called spin_button_alarm_hour and spin_button_alarm_min allow a user to enter or change hour and minute numeric values within the 24 hour time bounds (e.g. hours can be changed from 0 to 23 and minutes from 0 to 59). Using g_signal_connect(), the spin button called spin_button_alarm_hour is connected to the callback function in the program named callbk_spin_alarm_hour() using the “value-changed” state of the spin button. Likewise the spin button called spin_button_alarm_min is connected to a function named callbk_spin_alarm_min() again called when the spin button numerical value is changed. Within these functions the value of the spin button is set to an integer using gtk_spin_button_get_value_as_int() so that the variables m_alarm_hour and m_alarm_min can be set.
Deux objets GtkAdjustment, appelés adjustment_alarm_hour et adjustment_alarm_min, sont créés. Ces ajustements sont utilisés par les widgets GtkSpinButton pour définir les limites inférieure et supérieure des incréments. La documentation en ligne de l'API GTK4 indique que le constructeur gtk_adjustment_new() pour la création d'un nouvel objet GtkAdjustment prend en compte les paramètres suivants : valeur initiale, valeur minimale, valeur maximale, incrément de pas, incrément de page et taille de page.
Les widgets GtkSpinButton, appelés spin_button_alarm_hour et spin_button_alarm_min, permettent à l'utilisateur de saisir ou de modifier les valeurs numériques des heures et des minutes sur une période de 24 heures (par exemple, les heures peuvent être modifiées de 0 à 23 et les minutes de 0 à 59).
Grâce à g_signal_connect(), le bouton rotatif spin_button_alarm_hour est connecté à la fonction de rappel callbk_spin_alarm_hour() du programme, en utilisant son état « valeur modifiée ». De même, le bouton rotatif spin_button_alarm_min est connecté à une fonction callbk_spin_alarm_min(), appelée de même lorsque sa valeur numérique est modifiée. Dans ces fonctions, la valeur du bouton rotatif est définie sur un entier via gtk_spin_button_get_value_as_int(), ce qui permet de définir les variables m_alarm_hour et m_alarm_min.
Timer The GLib function g_timeout_add_seconds() can be used to create a timer. It allows a function to be called repeatedly until the function returns FALSE. The arguments are the interval (i.e. the time between calls to the function, in seconds), the function to call and the data to pass to the function. g_timeout_add_seconds(1, label_update, label_time); In this application, the first parameter is set to one second, the second parameter is set to the function named “label_update()” and the third to label_time. The label_update() function must match the signature of GSourceFunc which means that it must be a static member function, have return type of gboolean and have a parameter of gpointer. In this example it always returns TRUE and the gpointer data is the time label. The gpointer (generic pointer) was discussed in the last article and is untyped and requires casting. Here it is cast as a GtkLabel pointer using (GtkLabel*) so that the label_time widget can be updated with the time. See the GLib timeout_add_seconds() API information in the external links below for more information.
Minuterie
La fonction GLib g_timeout_add_seconds() permet de créer une minuterie. Elle permet d'appeler une fonction de manière répétée jusqu'à ce qu'elle renvoie FAUX. Les arguments sont l'intervalle (c'est-à-dire le temps entre les appels, en secondes), la fonction à appeler et les données à lui transmettre.
g_timeout_add_seconds(1, label_update, label_time);
Dans cette application, le premier paramètre est défini sur une seconde, le deuxième sur la fonction « label_update() » et le troisième sur label_time. La fonction label_update() doit correspondre à la signature de GSourceFunc, ce qui signifie qu'elle doit être une fonction membre statique, avoir un type de retour gboolean et un paramètre de gpointer. Dans cet exemple, elle renvoie toujours TRUE et les données du gpointer correspondent à l'étiquette de temps. Le gpointer (pointeur générique), abordé dans l'article précédent, est non typé et nécessite un cast. Ici, il est converti en pointeur GtkLabel via (GtkLabel*) afin que le widget label_time puisse être mis à jour avec l'heure. Pour plus d'informations, consultez les informations sur l'API GLib timeout_add_seconds() dans les liens externes ci-dessous.
Inside the function “label_update()” GDateTime is used. This combines a date and time into a single structure and provides many methods to manipulate dates and times. The function g_date_time_new_now_local() is used to get the hour and minute in the local time zone. Then g_date_time_format() is used to format the time value and then gtk_label_set_text() is used to set the time label text. If the hour value equals the m_alarm_hour and the minute value equals the m_alarm_min then an audio alarm WAV file called alarm.wav is played using the system command. Minimise The button widget called button_minimise connects to a callback named callbk_button_minimise() using the clicked state of the button. Again g_signal_connect() is used to link the button to the callback function named callbk_button_minimise() using the “clicked” state of the button. Notice that the window is passed as the gpointer parameter. This enables the use of gtk_window_minimize() to minimise the alarm clock when the button is clicked so that it is out of sight while it ticks away until the alarm time is reached.
La fonction « label_update() » utilise GDateTime. Celle-ci combine une date et une heure en une seule structure et fournit de nombreuses méthodes pour manipuler ces dates et heures. La fonction g_date_time_new_now_local() permet de récupérer l'heure et les minutes du fuseau horaire local. Ensuite, g_date_time_format() formate la valeur de l'heure, puis gtk_label_set_text() définit le texte de l'étiquette d'heure.
Si l'heure est égale à m_alarm_hour et les minutes à m_alarm_min, un fichier WAV d'alarme audio appelé alarm.wav est joué via la commande système.
Réduire
Le widget bouton appelé button_minimise se connecte à une fonction de rappel appelée callbk_button_minimise() en utilisant l'état cliqué du bouton. De nouveau, g_signal_connect() relie le bouton à la fonction de rappel appelée callbk_button_minimise() en utilisant l'état cliqué du bouton. Notez que la fenêtre est passée en paramètre gpointer. Cela permet d'utiliser gtk_window_minimize() pour minimiser le réveil lorsque le bouton est cliqué afin qu'il soit hors de vue pendant qu'il tourne jusqu'à ce que l'heure de l'alarme soit atteinte.
Grid Container The gtk_grid_attach() function is used to position the child widgets on the grid. The GTK4 API shows that it takes the following parameters: the grid pointer, the child widget pointer, the column, the row, the width and the height. The position of the child widget is determined by the column and row values. The number of “grid cells” that the child widget will occupy is determined by the width and height. For example, the button_minimise widget is positioned on the first column and on the fifth row. It has a width of four cells and a height of one. The function gtk_window_set_child() is used to set the grid as the child widget of the window and then gtk_window_present() is used to show the window. Make The Makefile to build the application is included in the download. As discussed in the first article run the “make” command in the project directory to build the alarm clock application. An executable called “alarmclock” is produced. Desktop File A desktop file for the alarm clock can be created using the application ID which is set to “org.gtk.alarmclock”. Create a directory called “Software” in the home directory and inside this a sub-directory called “alarmclock”. Place the alarmclock executable and the audio file alarm.wav in this. Then save a file called “org.gtk.alarmclock.desktop” to the hidden local directory “.local/share/applications” with the contents below. Substitute your own user name where it says “your-user-name”
Conteneur de grille
La fonction gtk_grid_attach() permet de positionner les widgets enfants sur la grille. L'API GTK4 indique qu'elle prend en compte les paramètres suivants : le pointeur de grille, le pointeur du widget enfant, la colonne, la ligne, la largeur et la hauteur. La position du widget enfant est déterminée par les valeurs de la colonne et de la ligne. Le nombre de cellules de la grille occupées par le widget enfant est déterminé par la largeur et la hauteur. Par exemple, le widget button_minimise est positionné sur la première colonne et la cinquième ligne. Sa largeur est de quatre cellules et sa hauteur d'une. La fonction gtk_window_set_child() permet de définir la grille comme widget enfant de la fenêtre, puis gtk_window_present() permet d'afficher la fenêtre.
Make
Le fichier Makefile permettant de compiler l'application est inclus dans le téléchargement. Comme indiqué dans le premier article, exécutez la commande « make » dans le répertoire du projet pour compiler l'application réveil. Un exécutable appelé « alarmclock » est généré.
Fichier Desktop
Un fichier Desktop pour le réveil peut être créé avec l'ID d'application « org.gtk.alarmclock ». Créez un répertoire « Software » dans le répertoire personnel, puis un sous-répertoire « alarmclock ». Placez-y l'exécutable du réveil et le fichier audio alarm.wav. Enregistrez ensuite un fichier « org.gtk.alarmclock.desktop » dans le répertoire local caché « .local/share/applications » avec le contenu ci-dessous. Remplacez votre nom d'utilisateur par « votre-nom-d'utilisateur ».
[Desktop Entry] Version=0.1.0 Type=Application Name=Alarm Clock Comment=Alarms Exec=/home/your-user-name/Software/alarmclock/alarmclock Path=/home/your-user-name/Software/alarmclock Icon=“time.svg” The alarm clock will pop up in the applications list so that it can be pinned to the dash. This article provides an overview of the source code which can be downloaded for further study. External Links GTK4 Widget Gallery https://docs.gtk.org/gtk4/visual_index.html GTK4 API documentation https://docs.gtk.org/gtk4/index.html GLib API documentation https://docs.gtk.org/glib/index.html GLib timeout_add_seconds https://docs.gtk.org/glib/func.timeout_add_seconds.html
[Desktop Entry] Version=0.1.0 Type=Application Name=Alarm Clock Comment=Alarms Exec=/home/your-user-name/Software/alarmclock/alarmclock Path=/home/your-user-name/Software/alarmclock Icon=“time.svg”
Le réveil apparaîtra dans la liste des applications et pourra être épinglé au tableau de bord.
Cet article présente un aperçu du code source, téléchargeable pour une étude plus approfondie.
Liens externes
Galerie de widgets GTK4 https://docs.gtk.org/gtk4/visual_index.html
Documentation de l'API GTK4 https://docs.gtk.org/gtk4/index.html
Documentation de l'API GLib https://docs.gtk.org/glib/index.html
GLib timeout_add_seconds https://docs.gtk.org/glib/func.timeout_add_seconds.html