issue222:gtk4
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Prochaine révision | Révision précédente | ||
| issue222:gtk4 [2025/11/02 18:52] – créée d52fr | issue222:gtk4 [2025/11/03 08:11] (Version actuelle) – d52fr | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | **As previously explained, GTK4 uses the GObject (GLib Object System) library to provide object-oriented programming (OOP) features using function-like macros. This article shows how to write a contact class so that contact object instances can be created with personal details (name, email, phone). These are then stored in a list using the GListStore class and a view widget called GtkColumnView exploited to display them. | ||
| - | As previously explained, | + | A screenshot of the GTK4 contacts application |
| - | A screenshot of the GTK4 contacts application that will be developed using Ubuntu 24.04 is shown above. | + | Comme expliqué précédemment, |
| + | Une capture d' | ||
| - | Object Oriented Programming (OOP) | + | **Object Oriented Programming (OOP) |
| OOP is a software design method that models the characteristics of real-world objects using software classes which have properties and methods. A class is a template or blueprint for how to build an object. Many object instances can be created from one given class. The main benefit of using the OOP approach is to make it easier to solve real-world problems by modelling natural objects as software objects. Identifying the state and behaviour for real-world objects is the starting point to begin thinking in terms of OOP. | OOP is a software design method that models the characteristics of real-world objects using software classes which have properties and methods. A class is a template or blueprint for how to build an object. Many object instances can be created from one given class. The main benefit of using the OOP approach is to make it easier to solve real-world problems by modelling natural objects as software objects. Identifying the state and behaviour for real-world objects is the starting point to begin thinking in terms of OOP. | ||
| - | 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. ** |
| - | Contact Class | + | 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' | ||
| + | |||
| + | En POO, l' | ||
| + | |||
| + | |||
| + | **Contact Class | ||
| A contact class which inherits from GObject will be created with properties for a person name, their email address, and telephone details. In a real contact management application, | A contact class which inherits from GObject will be created with properties for a person name, their email address, and telephone details. In a real contact management application, | ||
| Ligne 20: | Ligne 29: | ||
| Open and view the files person-contact.h, | Open and view the files person-contact.h, | ||
| - | 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' | ||
| + | |||
| + | Le code source complet de ce projet est disponible au téléchargement via le lien suivant : https:// | ||
| + | |||
| + | Ouvrez et consultez les fichiers person-contact.h, | ||
| + | |||
| + | Les fichiers person-contact.h et person-contact.c sont respectivement l' | ||
| - | 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(). |
| The macro G_DECLARE_FINAL_TYPE is used to declare a new class (i.e. register the new class to the type system). The FINAL in the macro name means that the contact class cannot be sub-classed. The macro is used as shown below. | The macro G_DECLARE_FINAL_TYPE is used to declare a new class (i.e. register the new class to the type system). The FINAL in the macro name means that the contact class cannot be sub-classed. The macro is used as shown below. | ||
| Ligne 28: | Ligne 48: | ||
| G_DECLARE_FINAL_TYPE(PersonContact, | G_DECLARE_FINAL_TYPE(PersonContact, | ||
| - | 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.** |
| - | 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. | + | Le fichier d' |
| - | Inside person_contact.c a structure is defined as shown below. | + | La macro G_DECLARE_FINAL_TYPE est utilisée pour déclarer une nouvelle classe (c' |
| + | G_DECLARE_FINAL_TYPE(PersonContact, | ||
| + | |||
| + | Le premier argument de cette macro est le nom de la classe enfant en camelCase, soit PersonContact. Le deuxième argument est person_contact, | ||
| + | |||
| + | |||
| + | **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. | ||
| + | < | ||
| struct _PersonContact | struct _PersonContact | ||
| { | { | ||
| Ligne 41: | Ligne 70: | ||
| gchar* phone; | gchar* phone; | ||
| }; | }; | ||
| + | </ | ||
| + | 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, | ||
| - | 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' |
| - | 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. | + | Dans le fichier person_contact.c, |
| + | |||
| + | < | ||
| + | struct _PersonContact | ||
| + | { | ||
| + | GObject parent_instance; | ||
| + | gchar* name; | ||
| + | gchar* email; | ||
| + | gchar* phone; | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | L' | ||
| + | |||
| + | |||
| + | **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 macro G_DEFINE_TYPE is used to implement a new GObject defining the basic structure for a new GObject type, including its class and instance initialisation functions. It is used to create custom object types as shown below. | The macro G_DEFINE_TYPE is used to implement a new GObject defining the basic structure for a new GObject type, including its class and instance initialisation functions. It is used to create custom object types as shown below. | ||
| Ligne 50: | Ligne 96: | ||
| G_DEFINE_TYPE (PersonContact, | G_DEFINE_TYPE (PersonContact, | ||
| - | 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, | ||
| + | |||
| + | La macro G_DEFINE_TYPE permet d' | ||
| + | |||
| + | G_DEFINE_TYPE(PersonContact, | ||
| + | |||
| + | 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. |
| enum { | enum { | ||
| Ligne 62: | Ligne 117: | ||
| }; | }; | ||
| - | 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.** |
| - | 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. | + | 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 ; |
| + | |||
| + | enum { | ||
| + | PROP_0, | ||
| + | PROP_NAME, | ||
| + | PROP_EMAIL, | ||
| + | PROP_PHONE, | ||
| + | LAST_PROP | ||
| + | }; | ||
| + | |||
| + | Tous les GObjects requièrent deux constructeurs : | ||
| + | |||
| + | |||
| + | **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. | ||
| GListStore | GListStore | ||
| Ligne 70: | Ligne 138: | ||
| At this stage a contact class has been written with the parent instance being GObject. By including the person-contact.h header in the main.c file, contact objects can be used. | At this stage a contact class has been written with the parent instance being GObject. By including the person-contact.h header in the main.c file, contact objects can be used. | ||
| - | 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.** |
| - | 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. | + | Le squelette de code présenté ici peut servir de modèle pour écrire d' |
| + | |||
| + | GListStore | ||
| + | |||
| + | À ce stade, une classe Contact a été écrite, son instance parente étant GObject. En incluant l' | ||
| + | |||
| + | 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' | ||
| + | |||
| + | |||
| + | **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.** | ||
| + | |||
| + | 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' | ||
| + | |||
| + | 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' | ||
| - | 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. | ||
| - | View Widgets | + | **View Widgets |
| View widgets such as GtkColumnView display data from a model. The GtkColumnView view widget is used to display a list of items using multiple columns. In this example, a column for the name, a column for the email, and a column for the phone details, are needed. To do this, they use a " | View widgets such as GtkColumnView display data from a model. The GtkColumnView view widget is used to display a list of items using multiple columns. In this example, a column for the name, a column for the email, and a column for the phone details, are needed. To do this, they use a " | ||
| Ligne 82: | Ligne 164: | ||
| Two callbacks are used. The callback called “callbk_setup” uses the gtk_list_item_set_child() function to associate a label widget with the list view. The second callback called “callbk_bind_name” is used to determine what is displayed on the label which in this case is the name property. | Two callbacks are used. The callback called “callbk_setup” uses the gtk_list_item_set_child() function to associate a label widget with the list view. The second callback called “callbk_bind_name” is used to determine what is displayed on the label which in this case is the name property. | ||
| - | 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' | ||
| + | Les widgets d' | ||
| + | Deux fonctions de rappel sont utilisées. La première, « callbk_setup », | ||
| - | External Links | + | Utilisez le Makefile fourni pour compiler l' |
| + | |||
| + | |||
| + | **External Links | ||
| GObject API | GObject API | ||
| Ligne 99: | Ligne 187: | ||
| G_DEFINE_FINAL_TYPE Macro | G_DEFINE_FINAL_TYPE Macro | ||
| + | https:// | ||
| + | |||
| + | Liens externes | ||
| + | |||
| + | API de GObject | ||
| + | https:// | ||
| + | |||
| + | Tutoriel sur GObject | ||
| + | https:// | ||
| + | |||
| + | La macro G_DECLARE_FINAL_TYPE | ||
| + | https:// | ||
| + | |||
| + | la macro G_DEFINE_FINAL_TYPE | ||
| https:// | https:// | ||
issue222/gtk4.1762105922.txt.gz · Dernière modification : 2025/11/02 18:52 de d52fr
