Outils pour utilisateurs

Outils du site


issue222:gtk4

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
issue222:gtk4 [2025/11/02 23:02] d52frissue222:gtk4 [2025/11/03 08:11] (Version actuelle) d52fr
Ligne 3: Ligne 3:
 A screenshot of the GTK4 contacts application that will be developed using Ubuntu 24.04 is shown above.** A screenshot of the GTK4 contacts application that will be developed using Ubuntu 24.04 is shown above.**
  
 +Comme expliqué précédemment, GTK4 utilise la bibliothèque GObject (GLib Object System) pour offrir des fonctionnalités de programmation orientée objet (POO) grâce à des macros. Cet article montre comment créer une classe Contact permettant de générer des instances d'objets Contact contenant des informations personnelles (nom, adresse e-mail, numéro de téléphone). Ces informations sont ensuite stockées dans une liste à l'aide de la classe GListStore et affichées grâce à un widget d'affichage appelé GtkColumnView.
 +
 +Une capture d'écran de l'application Contacts GTK4, développée sous Ubuntu 24.04, est présentée ci-dessus.
  
  
Ligne 10: Ligne 13:
  
 In OOP, inheritance allows a new class known as the child class or subclass to inherit properties and methods from an existing class known as the parent class which is often GObject. With GTK4, macros are used to create a new child or subclass using header (.h) and source code (.c) files. In the simplest case, the macro G_DECLARE_FINAL_TYPE() is used in the header file, and this is coupled with the macro G_DEFINE_FINAL_TYPE() in the source file. ** In OOP, inheritance allows a new class known as the child class or subclass to inherit properties and methods from an existing class known as the parent class which is often GObject. With GTK4, macros are used to create a new child or subclass using header (.h) and source code (.c) files. In the simplest case, the macro G_DECLARE_FINAL_TYPE() is used in the header file, and this is coupled with the macro G_DEFINE_FINAL_TYPE() in the source file. **
 +
 +Programmation orientée objet (POO)
 +
 +La POO est une méthode de conception logicielle qui modélise les caractéristiques des objets du monde réel à l'aide de classes logicielles dotées de propriétés et de méthodes. Une classe sert de modèle ou de plan pour la construction d'un objet. De nombreuses instances d'objets peuvent être créées à partir d'une même classe. Le principal avantage de la POO est de simplifier la résolution de problèmes concrets en modélisant les objets naturels comme des objets logiciels. Identifier l'état et le comportement des objets du monde réel est le point de départ de la réflexion en termes de POO.
 +
 +En POO, l'héritage permet à une nouvelle classe, appelée classe enfant ou sous-classe, d'hériter des propriétés et des méthodes d'une classe existante, appelée classe parente, souvent de type GObject. Avec GTK4, des macros sont utilisées pour créer une nouvelle classe enfant ou sous-classe à l'aide de fichiers d'en-tête (.h) et de code source (.c). Dans le cas le plus simple, la macro G_DECLARE_FINAL_TYPE() est utilisée dans le fichier d'en-tête, et elle est associée à la macro G_DEFINE_FINAL_TYPE() dans le fichier source.
 +
  
 **Contact Class **Contact Class
Ligne 20: Ligne 30:
  
 The files person-contact.h and person-contact.c are the header and source files for the contact class. Function declarations go into the header file and source code implementations go into the source code file. Functions implemented in person-contact.c can be used by other files in the project provided they are declared in the header file and are not private. ** The files person-contact.h and person-contact.c are the header and source files for the contact class. Function declarations go into the header file and source code implementations go into the source code file. Functions implemented in person-contact.c can be used by other files in the project provided they are declared in the header file and are not private. **
 +
 +Classe Contact
 +
 +Une classe Contact, héritant de GObject, sera créée avec des propriétés pour le nom, l'adresse e-mail et le numéro de téléphone d'une personne. Dans une application réelle de gestion de contacts, de nombreuses autres propriétés seraient présentes, notamment pour l'adresse postale.
 +
 +Le code source complet de ce projet est disponible au téléchargement via le lien suivant : https://github.com/crispinprojects/fullcircle
 +
 +Ouvrez et consultez les fichiers person-contact.h, person-contact.c et main.c pour suivre les explications ci-dessous.
 +
 +Les fichiers person-contact.h et person-contact.c sont respectivement l'en-tête et le code source de la classe Contact. Les déclarations de fonctions sont placées dans l'en-tête, tandis que leur implémentation se trouve dans le code source. Les fonctions implémentées dans person-contact.c peuvent être utilisées par d'autres fichiers du projet, à condition d'être déclarées dans l'en-tête et de ne pas être privées.
 +
  
 **The header file has standard C header guards and then includes glib-object.h which defines GObject. The G_BEGIN_DECLS and G_END_DECLS are the begin and end macro declarations. The #define is used to associate PERSON_TYPE_CONTACT with person_contact_get_type().  **The header file has standard C header guards and then includes glib-object.h which defines GObject. The G_BEGIN_DECLS and G_END_DECLS are the begin and end macro declarations. The #define is used to associate PERSON_TYPE_CONTACT with person_contact_get_type(). 
Ligne 28: Ligne 49:
  
 The first argument of this macro is the child class name in camel case i.e. PersonContact. The second argument is person_contact written in lower case and with an underscore. It is used as a function prefix. The third argument, PERSON, is the namespace, and is used as the first part of the name of the class. Choosing the right namespace is important to prevent naming conflicts and provide context, and in a larger application a more specific namespace related to the application name would be used. The fourth argument, CONTACT, is the object name. The last argument, GObject, is the parent class. The naming convention that has been used in the code is because macros require names in Camel case or words separated by an underscore “_”, which may not be obvious if this is the first time of writing a GObject in C.** The first argument of this macro is the child class name in camel case i.e. PersonContact. The second argument is person_contact written in lower case and with an underscore. It is used as a function prefix. The third argument, PERSON, is the namespace, and is used as the first part of the name of the class. Choosing the right namespace is important to prevent naming conflicts and provide context, and in a larger application a more specific namespace related to the application name would be used. The fourth argument, CONTACT, is the object name. The last argument, GObject, is the parent class. The naming convention that has been used in the code is because macros require names in Camel case or words separated by an underscore “_”, which may not be obvious if this is the first time of writing a GObject in C.**
 +
 +Le fichier d'en-tête contient les gardes d'en-tête C standard, puis inclut glib-object.h qui définit GObject. Les macros G_BEGIN_DECLS et G_END_DECLS sont les déclarations de début et de fin. La directive #define est utilisée pour associer PERSON_TYPE_CONTACT à la fonction person_contact_get_type().
 +
 +La macro G_DECLARE_FINAL_TYPE est utilisée pour déclarer une nouvelle classe (c'est-à-dire l'enregistrer auprès du système de types). Le terme FINAL dans le nom de la macro indique que la classe Contact ne peut pas être héritée. La macro s'utilise comme suit :
 +
 +G_DECLARE_FINAL_TYPE(PersonContact, person_contact, PERSON, CONTACT, GObject)
 +
 +Le premier argument de cette macro est le nom de la classe enfant en camelCase, soit PersonContact. Le deuxième argument est person_contact, écrit en minuscules avec un tiret bas. Il sert de préfixe à la fonction. Le troisième argument, PERSON, est l'espace de noms et constitue la première partie du nom de la classe. Choisir le bon espace de noms est important pour éviter les conflits de noms et fournir du contexte. Dans une application plus vaste, un espace de noms plus spécifique, lié au nom de l'application, sera utilisé. Le quatrième argument, CONTACT, est le nom de l'objet. Le dernier argument, GObject, est la classe parente. La convention de nommage utilisée dans le code est due au fait que les macros exigent des noms en CamelCase ou des mots séparés par un tiret bas « _ », ce qui peut ne pas être évident lors de la première utilisation d'un GObject en C.
 +
  
 **The next few declarations are accessor functions known as getters and setters. A getter function returns a property value while a setter function sets or updates a property value. There are three properties which are name, email and phone. **The next few declarations are accessor functions known as getters and setters. A getter function returns a property value while a setter function sets or updates a property value. There are three properties which are name, email and phone.
  
 Inside person_contact.c a structure is defined as shown below.  Inside person_contact.c a structure is defined as shown below. 
 +<nowiki>
 struct _PersonContact struct _PersonContact
 { {
Ligne 40: Ligne 70:
 gchar* phone; gchar* phone;
 }; };
 +</nowiki>
 The way in which inheritance works when using the GObject library is to put the parent type as the first field of the structure. In this case GObject is the parent instance. This makes available all the properties, methods, and signals of GObject to the subclass called PersonContact. Consequently, because PersonContact is a subclass of GObject the functions g_object_set() and g_object_get() can be used to set and get properties respectively.** The way in which inheritance works when using the GObject library is to put the parent type as the first field of the structure. In this case GObject is the parent instance. This makes available all the properties, methods, and signals of GObject to the subclass called PersonContact. Consequently, because PersonContact is a subclass of GObject the functions g_object_set() and g_object_get() can be used to set and get properties respectively.**
 +
 +Les déclarations suivantes sont des fonctions d'accès appelées getters et setters. Un getter renvoie la valeur d'une propriété, tandis qu'un setter la définit ou la met à jour. Il y a trois propriétés : name, email et phone.
 +
 +Dans le fichier person_contact.c, une structure est définie comme suit :
 +
 +<nowiki>
 +struct _PersonContact
 +{
 +GObject parent_instance; // parent
 +gchar* name;
 +gchar* email;
 +gchar* phone;
 +};
 +</nowiki>
 +
 +L'héritage, lorsqu'on utilise la bibliothèque GObject, consiste à placer le type parent comme premier champ de la structure. Ici, GObject est l'instance parente. Cela rend toutes les propriétés, méthodes et signaux de GObject accessibles à la sous-classe PersonContact. Par conséquent, puisque PersonContact est une sous-classe de GObject, les fonctions g_object_set() et g_object_get() peuvent être utilisées pour définir et obtenir respectivement les propriétés.
 +
  
 **The rest of the fields are used for the PersonContact properties namely name, email and phone. The name, email and phone variables are of type gchar*. Just to note that gchar is an alternate name for the existing C data type char (i.e. a typedef) and is used to be consistent with the GTK4 API documentation. **The rest of the fields are used for the PersonContact properties namely name, email and phone. The name, email and phone variables are of type gchar*. Just to note that gchar is an alternate name for the existing C data type char (i.e. a typedef) and is used to be consistent with the GTK4 API documentation.
Ligne 50: Ligne 97:
  
 The first argument is the name of the new type, in Camel case, which in this case is PersonContact. The second argument is the name of the new type, in lowercase, with words separated by an underscore “_”, which in this case is person_contact. The third argument is the GType of the parent type, which is G_TYPE_OBJECT because GObject is the parent class. ** The first argument is the name of the new type, in Camel case, which in this case is PersonContact. The second argument is the name of the new type, in lowercase, with words separated by an underscore “_”, which in this case is person_contact. The third argument is the GType of the parent type, which is G_TYPE_OBJECT because GObject is the parent class. **
 +
 +Les champs restants sont utilisés pour les propriétés de PersonContact, à savoir nom, email et téléphone. Les variables nom, email et telephone sont de type gchar*. Il est important de noter que gchar est un synonyme du type de données C char (c'est-à-dire un typedef) et est utilisé par souci de cohérence avec la documentation de l'API GTK4.
 +
 +La macro G_DEFINE_TYPE permet d'implémenter un nouvel objet GObject définissant la structure de base d'un nouveau type GObject, y compris ses fonctions d'initialisation de classe et d'instance. Elle sert à créer des types d'objets personnalisés, comme illustré ci-dessous.
 +
 +G_DEFINE_TYPE(PersonContact, person_contact, G_TYPE_OBJECT);
 +
 +Le premier argument est le nom du nouveau type, en notation CamelCase, ici PersonContact. Le deuxième argument est le nom du nouveau type, en minuscules, les mots étant séparés par un tiret bas « _ », ici person_contact. Le troisième argument est le GType du type parent, qui est G_TYPE_OBJECT car GObject est la classe parente.
 +
  
 **An enum is used to define the properties PROP_NAME, PROP_EMAIL and PROP_PHONE. All properties need a unique identifier and the zero property cannot be used and so a dummy property called PROP_0 is created. LAST_PROP is the number of properties. **An enum is used to define the properties PROP_NAME, PROP_EMAIL and PROP_PHONE. All properties need a unique identifier and the zero property cannot be used and so a dummy property called PROP_0 is created. LAST_PROP is the number of properties.
Ligne 62: Ligne 118:
  
 Two constructors are required by all GObjects which are the class_init and the object init functions. In this case, these are the person_contact_class_init() and person_contact_init(). The person_contact_class_init() is the class constructor which is called only once and gets run on the first time an instance of the object is created. Inside the person_contact_class_init() constructor properties are defined using g_param_spec_string. Arguments are provided to give a property a name and range. These properties have to be accessed using the getter and setter functions. The getter and setter functions are written to get and set the name, email and phone properties. The function person_contact_dispose(GObject *object) is the destructor.** Two constructors are required by all GObjects which are the class_init and the object init functions. In this case, these are the person_contact_class_init() and person_contact_init(). The person_contact_class_init() is the class constructor which is called only once and gets run on the first time an instance of the object is created. Inside the person_contact_class_init() constructor properties are defined using g_param_spec_string. Arguments are provided to give a property a name and range. These properties have to be accessed using the getter and setter functions. The getter and setter functions are written to get and set the name, email and phone properties. The function person_contact_dispose(GObject *object) is the destructor.**
 +
 +Une énumération est utilisée pour définir les propriétés PROP_NAME, PROP_EMAIL et PROP_PHONE. Chaque propriété nécessite un identifiant unique et la valeur zéro ne peut être utilisée ; une propriété factice nommée PROP_0 est donc créée. LAST_PROP représente le nombre de propriétés.
 +
 +enum {
 +PROP_0,
 +PROP_NAME,
 +PROP_EMAIL,
 +PROP_PHONE,
 +LAST_PROP
 +};
 +
 +Tous les GObjects requièrent deux constructeurs : les fonctions d'initialisation de classe et d'objet. Dans ce cas, il s'agit de person_contact_class_init() et person_contact_init(). Le constructeur person_contact_class_init() est le constructeur de classe ; il est appelé une seule fois, lors de la création de la première instance de l'objet. À l'intérieur de ce constructeur, les propriétés sont définies à l'aide de g_param_spec_string. Des arguments sont fournis pour nommer et définir la plage de valeurs de chaque propriété. Ces propriétés sont accessibles via les fonctions d'accès (getter et setter). Ces fonctions permettent d'obtenir et de modifier les propriétés « name », « email » et « phone ». La fonction `person_contact_dispose(GObject *object)` est le destructeur.
 +
  
 **The skeletal code presented here can be used as boilerplate code for writing other GObject classes although only properties are used in this example, and no signals. The GObject API provides further information. **The skeletal code presented here can be used as boilerplate code for writing other GObject classes although only properties are used in this example, and no signals. The GObject API provides further information.
Ligne 70: Ligne 139:
  
 A GListStore acts as a simple array-like list that stores objects derived from GObject such as contact objects. It is a container that holds a collection of objects providing methods to append, insert, remove, find, and sort them. GListStore is a specific implementation of the more general GListModel interface which provides a standardised way to represent a list of objects for use with view widgets. View widgets such as GtkColumnView are used to display data from a model. This is known as model view design.** A GListStore acts as a simple array-like list that stores objects derived from GObject such as contact objects. It is a container that holds a collection of objects providing methods to append, insert, remove, find, and sort them. GListStore is a specific implementation of the more general GListModel interface which provides a standardised way to represent a list of objects for use with view widgets. View widgets such as GtkColumnView are used to display data from a model. This is known as model view design.**
 +
 +Le squelette de code présenté ici peut servir de modèle pour écrire d'autres classes GObject, bien que cet exemple n'utilise que des propriétés, sans signaux. L'API de GObject fournit des informations complémentaires.
 +
 +GListStore
 +
 +À ce stade, une classe Contact a été écrite, son instance parente étant GObject. En incluant l'en-tête person-contact.h dans le fichier main.c, il est possible d'utiliser des objets Contact.
 +
 +Un GListStore se comporte comme une simple liste, semblable à un tableau, qui stocke des objets dérivés de GObject, tels que des objets Contact. Il s'agit d'un conteneur qui gère une collection d'objets et propose des méthodes pour les ajouter, les insérer, les supprimer, les rechercher et les trier. GListStore est une implémentation spécifique de l'interface plus générale GListModel, qui fournit une méthode standardisée pour représenter une liste d'objets destinés à être utilisés avec des widgets d'affichage. Ces widgets, tels que GtkColumnView, servent à afficher les données d'un modèle. On parle alors de conception modèle-vue.
 +
  
 **The code below shows how to create a GListModel with a GListStore used to store two fictitious contacts “Mr Jellyfish” and “Mr Puffin”, named after Ubuntu releases. For example, the PersonContact pointer called *contact1 is created using the g_object_new() constructor. This constructor creates a new instance of a GObject subtype using its type which in this case is PERSON_TYPE_CONTACT. The g_object_set() function sets the properties of an object and is used to set the name, email and phone properties. **The code below shows how to create a GListModel with a GListStore used to store two fictitious contacts “Mr Jellyfish” and “Mr Puffin”, named after Ubuntu releases. For example, the PersonContact pointer called *contact1 is created using the g_object_new() constructor. This constructor creates a new instance of a GObject subtype using its type which in this case is PERSON_TYPE_CONTACT. The g_object_set() function sets the properties of an object and is used to set the name, email and phone properties.
  
 The g_list_store_new() function is used to create a new GListStore and then g_list_store_append() is used to add PersonContact objects to the store. The store can be thought of as holding rows of contact details which can then be displayed using a view widget.** The g_list_store_new() function is used to create a new GListStore and then g_list_store_append() is used to add PersonContact objects to the store. The store can be thought of as holding rows of contact details which can then be displayed using a view widget.**
 +
 +Le code ci-dessous montre comment créer un GListModel avec un GListStore utilisé pour stocker deux contacts fictifs, « Mr Jellyfish » et « Mr Puffin », nommés d'après des versions d'Ubuntu. Par exemple, le pointeur PersonContact nommé *contact1 est créé à l'aide du constructeur g_object_new(). Ce constructeur crée une nouvelle instance d'un sous-type GObject en utilisant son type, ici PERSON_TYPE_CONTACT. La fonction g_object_set() définit les propriétés d'un objet et sert à définir le nom, l'adresse e-mail et le numéro de téléphone.
 +
 +La fonction g_list_store_new() est utilisée pour créer un nouveau GListStore, puis g_list_store_append() est utilisée pour ajouter des objets PersonContact au magasin. Le magasin peut être considéré comme contenant des lignes de détails de contact qui peuvent ensuite être affichées à l'aide d'un widget d'affichage.
 +
  
 **View Widgets **View Widgets
Ligne 83: Ligne 166:
 Use the Makefile in the download to build the application which produces an executable called “addressbook”. In the next article, the application will be expanded to manipulate contact information and save and open data.** Use the Makefile in the download to build the application which produces an executable called “addressbook”. In the next article, the application will be expanded to manipulate contact information and save and open data.**
  
 +Widgets d'affichage
  
 +Les widgets d'affichage, tels que GtkColumnView, permettent d'afficher les données d'un modèle. Le widget GtkColumnView sert à afficher une liste d'éléments sur plusieurs colonnes. Dans cet exemple, une colonne est nécessaire pour le nom, une pour l'adresse e-mail et une pour le numéro de téléphone. Pour ce faire, ils utilisent le modèle de conception « factory », qui simplifie la création des objets. La factory est responsable de la création de la représentation visuelle et une factory doit être créée pour chaque colonne. L'extrait de code de la page suivante montre comment une factory est créée pour la colonne « name ».
 +
 +Deux fonctions de rappel sont utilisées. La première, « callbk_setup », utilise la fonction gtk_list_item_set_child() pour associer un widget Label à la vue de liste. La seconde, « callbk_bind_name », détermine le contenu affiché dans le Label, ici la propriété name.
 +
 +Utilisez le Makefile fourni pour compiler l'application, qui générera un exécutable nommé « addressbook ». Dans le prochain article, l'application sera étendue pour permettre la manipulation des informations de contact, ainsi que l'enregistrement et l'ouverture de données.
  
  
Ligne 99: Ligne 188:
 G_DEFINE_FINAL_TYPE Macro G_DEFINE_FINAL_TYPE Macro
 https://docs.gtk.org/gobject/func.DEFINE_FINAL_TYPE.html** https://docs.gtk.org/gobject/func.DEFINE_FINAL_TYPE.html**
 +
 +Liens externes
 +
 +API de GObject
 +https://docs.gtk.org/gobject/
 +
 +Tutoriel sur GObject
 +https://docs.gtk.org/gobject/tutorial.html
 +
 +La macro G_DECLARE_FINAL_TYPE
 +https://docs.gtk.org/gobject/func.DECLARE_FINAL_TYPE.html
 +
 +la macro G_DEFINE_FINAL_TYPE
 +https://docs.gtk.org/gobject/func.DEFINE_FINAL_TYPE.html
  
issue222/gtk4.1762120934.txt.gz · Dernière modification : 2025/11/02 23:02 de d52fr