QtAda application usualy creates own building blocks by subclassing of
QObject or one of it subclass.
QObject subclasses can override inherited
operations and define own signals and slots.
When you create custom subclass from the QObject
class or one of it subclass you also must generate Qt meta information
for your class using Ada-aware Meta Object Compiler.
QtAda provides two packages for each QObject
subclass. First package contains declaration of the interface type
and subprograms for the public operations of the class. This package
supposes to be used everywhere in the application. Use of the
interface type hides details of the actual class implementation from
the application. This package called Qt4.<ClassName> by
convention. Second package contains declaration of the tagged type
and subprograms for the private operations of the class. This package
supposed to be used by the application for subclassing only. This
package called Qt4.<ClassName>.Impl. We recommend to follow to
this schema, but it is not required.
Thus, when you subclassing QObject class or
one of the it subclasses you must declare your own interface type
derived from the interface type of the superclass and your own tagged
type derived from both the tagged type of the superclass and your
interface type.
Pragma Q_Object provides information about new class to the Ada-aware Meta Object Compiler. It must be used for each custom class. It have following parameters:
interface type name of public interface of the class
tagged type name of private implementation of the class
class name is used for class in the Qt Meta System
For example, when we subclassing
MyWidget from the
QWidget class, we will create
my_widgets.ads file for public interface of the
class:
with Qt4.Widgets; package My_Widgets is type My_Widget is limited interface and Qt4.Widgets.Q_Widget; type My_Widget_Access is access all My_Widget'Class; end My_Widgets;
and my_widgets-impl.ads file for implementation
of the class:
with Qt4.Widgets.Impl;
package My_Widgets.Impl is
type My_Widget_Impl is new Qt4.Widgets.Impl.Q_Widget_Impl
and My_Widget with private;
pragma Q_Object (My_Widget, My_Widget_Impl, "MyWidget");
private
type My_Widget_Impl is new Qt4.Widgets.Impl.Q_Widget_Impl
and My_Widget with null record;
end My_Widgets.Impl;
An ordinary subprogram must be declared for each signals and slots. The type of the first parameter of the such subprograms must be of class's tagged type or classwide type of class's tagged type or anonimous access type of tagged type or classwide tagged type.
Signals and slots subprograms must be marked for the Ada-aware Meta Object Compiler with pragma Q_Signal and Q_Slot. Both have same set of parameters:
name of the class's tagged type
name of the signal or slot subprogram
name and profile of the signal/slot in the Qt Meta System format
For example:
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()");
Implementation of the signal subprogram is generated by the Ada-aware Meta Object Compiler. You must declare signal subprogram as separate compilation unit in the package body:
procedure My_Signal (Self : not null access My_Widget_Impl) is separate;
Implementation of the slot subprogram provided by the user:
procedure My_Slot (Self : not null access My_Widget_Impl) is
begin
null;
end My_Slot;
Information for the Qt Meta System is generated by the Ada-aware Meta Object Compiler. It takes the name of the class's implementation package package, analyzes it and generate child package called Moc with the information for the Qt Meta System. If custom class has own signals Ada-aware Meta Object Compiler also generates it implementation in the separate compilation units.
Child package Moc generated by the Ada-aware Meta Object Compiler must be "withed" somewhere in the application code to be elaborated as part of the application. It is recommended to add it to the list of the context clauses in the constructors package.
Every constructor for the custom class must call constructor of the superclass. It is very important to call constructor of the superclass before any others actions. Superclass's constructors are placed in the subpackage Constructors of the Qt4.<ClassName>.Impl package.
For example, follow is an implementation of the constructor
subprogram for MyWidget class:
with My_Widgets.Impl.Moc;pragma Unreferenced (My_Widgets.Impl.Moc); package body My_Widgets.Constructors is ------------ -- Create -- ------------ function Create return not null My_Widget_Access is Self : constant not null My_Widgets.Impl.My_Widget_Impl_Access := new My_Widgets.Impl.My_Widget_Impl; begin Qt4.Widgets.Impl.Constructors.Initialize (Self); -- others actions return My_Widget_Access (Self); end Create; end My_Widgets.Constructors;
It is recommended to add "with" context clause for the class's meta information package generated by Ada-aware Meta Object Compiler in the class's constructors package. |