Subclassing notes

QObject subclassing

QObject is a most important class in the Qt framework. Only very simple QtAda applications don't use its own subclasses of the QObject.

You must do several steps for declare QObject subclass:

  • declare tagged type which directly or indirectly derived from the Qt4.Objects.Impl.Q_Object_Impl tagged type
  • declare user's signals and slots subprograms and mark them by corresponding amoc pragmasl and declare all signals subprograms as separate compilation units
  • declare constructor(s) subprogram(s) and place call to the parent tagged type constructor before any others actions
  • "with" meta information package somewhere in the program's code
  • generate meta information package and signals subprograms implementation using amoc

Tagged type

Two examples of the tagged type declarations present below. First example declare subclass from the QWidget class, and second example declare sublcass from the QMainWindow class.

with Qt4.Widgets.Impl;

package My_Widgets.Impl is

   type My_Widget_Impl is new Qt4.Widgets.Impl.Q_Widget_Impl with private;

   ...

end My_Widgets.Impl;
with Qt4.Main_Windows.Impl;

package My_Main_Windows.Impl is

   type My_Main_Window_Impl is
     new Qt4.Main_Windows.Impl.Q_Main_Window_Impl with private;

   ...

end My_Main_Windows.Impl;

Signals and slots subprograms

with Qt4.Widgets.Impl;

package My_Widgets.Impl is

   type My_Widget_Impl is new Qt4.Widgets.Impl.Q_Widget_Impl with private;

   procedure My_Slot (Self : not null access My_Widget_Impl);
   pragma Q_Slot (My_Widget_Impl, My_Slot, "mySlot()");

   procedure My_Signal (Self : not null access My_Widget_Impl);
   pragma Q_Signal (My_Widget_Impl, My_Signal, "mySignal()");

   ...

end My_Widgets.Impl;

package body My_Widgets.Impl is

   procedure My_Slot (Self : not null access My_Widget_Impl) is
   begin
      null;
   end My_Slot;

   procedure My_Signal (Self : not null access My_Widget_Impl) is separate;

end My_Widgets.Impl;

Constructors

Constructor subprogram must call Initialize subprogram from the superclass's package, and call Set_Dynamically_Allocated for the constructed object before doing ant others actions. It is recommended to "with" meta information package in the constructors' package body.

with My_Widgets.Impl.Moc;

package body My_Widgets.Constructors is

   function Create return not null access My_Widget'Class is
      X : Qt4_Entities.Limited_Entity_Access
        := new My_Widgets.Impl.My_Widget_Impl;
      --  This is a GNAT GPL 2008 bug workaround 

   begin
      return Returns : not null access My_Widget'Class
        := My_Widget'Class (X.all)'Access
      do
         declare
            R : My_Widgets.Impl.My_Widget_Impl'Class
              renames My_Widgets.Impl.My_Widget_Impl'Class (Returns.all);

         begin
            Qt4.Widgets.Impl.Constructors.Initialize (R'Access);
            R.Set_Dynamically_Allocated;

            --  others actions
         end;
      end return;
   end Create;

end My_Widgets.Constructors;
with My_Main_Windows.Impl.Moc;

package body My_Main_Windows.Constructors is

   function Create return not null access My_Main_Window'Class is
      X : Qt4_Entities.Limited_Entity_Access
        := new My_Main_Windows.Impl.My_Main_Window_Impl;
      --  This is a GNAT GPL 2008 bug workaround 

   begin
      return Returns : not null access My_Main_Window'Class
        := My_Main_Window'Class (X.all)'Access
      do
         declare
            R : My_Main_Windows.Impl.My_Main_Window_Impl'Class
              renames My_Main_Windows.Impl.My_Main_Window_Impl'Class
                       (Returns.all);

         begin
            Qt4.Main_Windows.Impl.Constructors.Initialize (R'Access);
            R.Set_Dynamically_Allocated;

            --  others actions
         end;
      end return;
   end Create;

end My_Main_Windows.Constructors;