Les Callback en Ada

29 views
Skip to first unread message

Danielle Mandi Mayagha

unread,
Sep 15, 2021, 10:29:58 PMSep 15
to
Salut Salut Je viens avec un tout petit (un gros enfaite) problème qui me sauf un peu le cerveau. bon voila! j'essaie de faire un Callback avec un Bouton mais le souci c'est que ce bon vieux Gnat me dit ceci ( pour info je suis carrément nul en anglais😊😛) :
Instantiation error at gtk-handlers.ads : 1039
Subprogram must not be deeper than access type.

plus loin Gnat dit encore ceci :
No candidate interpretations match the actuals:
expected type "handler" defined at gtk-marshaller.ads :395, instance at gtk-handlers :918 , instance at line 10.
Found type access to procedure "Stop_Program" defined at line 38.
=> in call to "to_marshaller" at gtk-handlers.ads :959, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :954, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :949, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :944, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :939, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :935, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :931, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :927, ainstance at line 10
=> in call to "to_marshaller" at gtk-handlers.ads :923, ainstance at line 10

voici mon code :

WITH Gtk.Main; USE Gtk.Main;
WITH Gtk.Widget; USE Gtk.Widget;
WITH Gtk.Window; USE Gtk.Window;
WITH Gtk.Enums; USE Gtk.Enums;
WITH Gtk.Button; USE Gtk.Button;
WITH Gtk.Handlers;

Procedure Test is

Package P_Callback is new Gtk.Handlers.Callback (Gtk_Widget_Record);
USE P_Callback;

Procedure Stop_Program ( Emetteur : Gtk_Widget_Record'Class ) is
Pragma Unreferenced (Emetteur);
begin
Main_Quit;

end Stop_Program;

Win : Gtk_Window;
Bouton : Gtk_Button;

begin
Init;

Gtk_New (Win);
Win.Set_Default_Size (600,400);

Gtk_New (Bouton,"Le Bouton");


Win.Add (Bouton);

P_Callback.Connect (Bouton,"Clicked", To_marshaller (Stop_Program'Access));

Win.Show_All;
Main;
end Test;

Voila pour vous dire vrai je ne vois aucun probleme donc si quelqu'un pouvait m'expliquer ce qui cloche j'en serai vraiment ravi.

pour info je suis sur Windows10 et j'utilise la version Gnat 2020.

J-P. Rosen

unread,
Sep 16, 2021, 4:48:41 AMSep 16
to
Le 16/09/2021 à 04:29, Danielle Mandi Mayagha a écrit :
> Salut Salut Je viens avec un tout petit (un gros enfaite) problème qui me sauf un peu le cerveau. bon voila! j'essaie de faire un Callback avec un Bouton mais le souci c'est que ce bon vieux Gnat me dit ceci ( pour info je suis carrément nul en anglais😊😛) :
> Instantiation error at gtk-handlers.ads : 1039
> Subprogram must not be deeper than access type.
>
[...]

> voici mon code :
>
> WITH Gtk.Main; USE Gtk.Main;
> WITH Gtk.Widget; USE Gtk.Widget;
> WITH Gtk.Window; USE Gtk.Window;
> WITH Gtk.Enums; USE Gtk.Enums;
> WITH Gtk.Button; USE Gtk.Button;
> WITH Gtk.Handlers;
>
> Procedure Test is
>
> Package P_Callback is new Gtk.Handlers.Callback (Gtk_Widget_Record);
> USE P_Callback;
>
> Procedure Stop_Program ( Emetteur : Gtk_Widget_Record'Class ) is
> Pragma Unreferenced (Emetteur);
> begin
> Main_Quit;
>
> end Stop_Program;
Ici, Stop_Program est un sous-programme interne à la procédure Test
>
> Win : Gtk_Window;
> Bouton : Gtk_Button;
>
> begin
> Init;
>
> Gtk_New (Win);
> Win.Set_Default_Size (600,400);
>
> Gtk_New (Bouton,"Le Bouton");
>
>
> Win.Add (Bouton);
>
> P_Callback.Connect (Bouton,"Clicked", To_marshaller (Stop_Program'Access));
Le type attendu par To_Marshaller est un pointeur global. On ne peut lui
passer un sous-programme local, car il y aurait un risque de pouvoir
accéder au sous-programme après être sorti de sa portée.

Le plus simple: sors Stop_Program de Test en le mettant dans un fichier
séparé. (bien sûr, pour pouvoir y accéder, Test devra faire un "with
Stop_Program;")


--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52
https://www.adalog.fr

Danielle Mandi Mayagha

unread,
Sep 16, 2021, 7:20:50 PMSep 16
to
merci beaucoup ça fonctionne tres bien maintenant

Danielle Mandi Mayagha

unread,
Sep 19, 2021, 8:51:17 PMSep 19
to
Salut désolé encore si je dérange mais j'ai un second souci que j'arrive pas à résoudre( voila je donne un exemple du code apres j'explique le probleme)

ficfier.ads

with Gtk.File_chooser_dialog; use gtk.file_file_chooser_dialog;
with gtk.widget; use gtk.widget;
with gtk.handlers;

package P_fichier is

type T_Type is record

F : Gtk_file_chooser_dialog;

end record;

package Callback is new gtk.handlers.user_callback (gtk_widget_record, P_fichier.T_Type);

use Callback;

Procedure Stop_Program ( emetteur : access gtk_widget_record;
object : out P_fichier.T_Type );

end P_fichier;

fichier.adb

package body P_fichier is

Procedure Stop_Program is (emetteur : access gtk_widget_record;
object : out P_fichier.T_type ) is
pragma Unreferenced (emetteur);

begin

gtk_new (Object.F, "ajout du fichier", action_Save, null);

end Stop_Program;
end P_fichier;

main_program.adb

with gtk.main; use gtk.main;
with gtk.window; use gtk.window;
with gtk.button; use gtk.button;
with P_fichier; use P_fichier;

Procedure main_Program is

win : gtk_window;
bouton : gtk_button;

begin
init;

gtk_new (win);
win.set_default_size (600,400);

gtk_new (bouton,"ouvrir le fichier");

declare

Object : T_Type;

begin

P_fichier.callback.connect (bouton,s signal_clicked, callback.to_marshaller (stop_program'
access, Object, false );

end ;

win.Add (bouton);
win.show_all;
main;
end main_program;

voila le probleme est que le programme affiche le meme message d'erreur que precedent pourtant j'ai bien mis Stop_Program dans un fichier separe. mais je ne comprend pas j'ai essayé avec Object_connect mais c'est toujours pareil.

DrPi

unread,
Sep 20, 2021, 1:07:03 PMSep 20
to
Bonjour,

Le 20/09/2021 à 02:51, Danielle Mandi Mayagha a écrit :
...
A première lecture du programme, le problème n'est plus avec
stop_program mais avec Object.
Object n'existe qu'entre declare et le end correspondant.
Il n'est donc pas possible de l'utiliser dans une callback.

Nicolas

Danielle Mandi Mayagha

unread,
Sep 21, 2021, 10:31:21 AMSep 21
to
Ah j'ai déjà essayé cela mais ça ne marche toujours pas

Ludovic Brenta

unread,
Sep 21, 2021, 1:09:45 PMSep 21
to
Danielle Mandi Mayagha <dmandi...@gmail.com> writes:
> package Callback is new gtk.handlers.user_callback (gtk_widget_record, P_fichier.T_Type);
>
> use Callback;
>
> Procedure Stop_Program ( emetteur : access gtk_widget_record;
> object : out P_fichier.T_Type );
>

Cette procédure n'obéit pas au type Gtk.Handlers.User_Callback.Handler:

type Handler is access procedure
(Widget : access Widget_Type'Class; -- OK
Params : Glib.Values.GValues; -- ignoré
User_Data : User_Type); -- pas OK, tu as dit "out P_Fichier.T_Type"

À mon avis tu peux simplifier ton programme. Tu n'as pas besoin d'un
type User_Data. Si tu veux ouvrir un fichier, tu peux créer le dialogue
comme variable locale dans ta procédure:

package body P is
procedure On_File_Open (Button : Gtk.Button.Gtk_Button) is
Dialog : Gtk_File_Chooser_Dialog;
begin
Gtk_New (Dialog);
if Dialog.Run then
-- OK, proceed with the file selected
else
-- user cancelled the dialog
end if;
end On_File_Open;
end P;

procedure Main is
Window : Gtk_Window;
Button : Gtk_Button;
begin
Init;
Gtk_New (Window);
Window.Set_Default_Size (600,400);
Gtk_New (Button, "ouvrir le fichier");
Window.Add (Button);
Button.On_Clicked (Call => P.On_File_Open'Access);
Window.Show_All;
Main;
end Main;

Maintenant, si tu veux récupérer le nom du fichier et le stocker dans
une variable non locale, je te conseille de faire une extension de type
pour ta *fenêtre*:

package Main_Window is
type Record_T is new Gtk.Window.Gtk_Window_Record with private;
type T is access all Record_T'Class;
procedure Gtk_New (Window : out T);
private
type Record_T is new Gtk.Window.Gtk_Window_Record with record
File_Name : Gtk.Label.Gtk_Label;
end record;
end Main_Window;

package body Main_Window is
procedure On_File_Open (Self : access Glib.Object.GObject_Record'Class) is
-- Conformant with Gtk.Button.Cb_GObject_Void
Window : T := T (Self);
Dialog : Gtk_File_Chooser_Dialog;
begin
Gtk_New (Dialog);
if Dialog.Run then
-- OK, proceed with the file selected
Window.Label.Set_Text (Dialog.Get_Filename);
else
-- user cancelled the dialog
Window.Label.Set_Text ("");
end if;
end On_File_Open;

procedure Gtk_New (Window : out T) is
Button : Gtk.Button.Gtk_Button;
begin
Gtk.Window.Gtk_New (Window);
Window.Set_Default_Size (600,400);
Gtk_New (Button, "ouvrir le fichier");
Window.Add (Button);
Button.On_Clicked (Call => On_File_Open'Access, Slot => Window);
-- On_File_Open will receive the specified Window, not the button, as its Self parameter
Gtk_New (Window.Label, "");
Window.Add (Label);
Window.Show_All;
end Gtk_New;
end Main_Window;

procedure Main is
Window : Main_Window.T;
begin
Gtk.Main.Init;
Main_Window.Gtk_New (Window);
Gtk.Main.Main;
end Main;

--
Ludovic Brenta.
The senior support staff transitions our supportive and/or market-based transformation process round-the-clock.
Reply all
Reply to author
Forward
0 new messages