Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
What's behind of Visual CLX Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
What are hook-objects in a Qt application? 18-Aug-04
Category
System
Language
Kylix All Versions
Views
698
User Rating
7
# Votes
1
Replies
0
Publisher:
Kleiner, Max
Reference URL:
Max Kleiner
			Beginning with Kylix needs some understanding between signals and slots, the way 
Linux/Qt deals with events and the Qt-library


VisualCLX is the part of CLX that represents the Visual Components that would 
noramlly reside in the TWinControl hierarchy in the VCL. 
VisualCLX framework is a set of classes that represent Visual Controls but have to 
work (if possible) on both MS Windows and X in Linux. 
The controls represented by the VisualCLX components are implemented by a C++ class 
library called Qt and widgets, from the Norwegian development company called 
Trolltech. Qt is also available on Windows. 

- The VCL TWinControl class is called TWidgetControl 

Qt is a C++ class library, cause of differences in C++ and OP 
(ObjectPascal)details, an OP program cannot directly manipulate Qt widgets. 
Instead, VisualCLX makes use of an additional library, called the Qt interface 
library (written in C++ as libqtintf.so) which exports all the Qt functionality in 
a manner that is accessible to OP code. 
The import unit for this interface library is called Qt.pas but this means that 
rather than being declared as classes, the Qt widget methods are all imported as 
flat methods or strictly speaking functions. 

We define a flat method as a method of a class that is declared as a standalone 
subroutine or function. 

However, since at the C++ side they are indeed classes, almost every flat method 
takes one extra parameter, which is the reference to the Qt widget. You think this 
might slow applications but most of the time you won't measure any difference in 
run-time behaviour. 

So what's the difference in a architectural manner: 
In a known OP application, you call methods via object references, e.g.: 
1   
2   myButton.setBounds(15, 15, 65, 35); 

Turning the method into a flat method, the object reference is passed as the first 
parameter so the method code knows which instance it should be invoking. Here is a 
"it goes almost like this" example flat method, which is equivalent to the method 
just used: 
3   
4   QButton_SetBounds(myButton, 15, 15, 65, 35); 

or in a Kylix Qt-manipulation: 
5   
6   uses  Qt, QTypes; 
7     var  Btn: QButtonH; 
8     Btn := QButton_create(Handle, PChar('Btn')); 
9     QButton_setGeometry(Btn, 15, 15, 65, 35); 

Of course you would normally have no need to write code like this as a QButton does 
it all for you, but it serves as a simplified example of how CLX components do 
their thing by using the CLXDisplayAPI. 


What's the CLXDisplayAPI 
------------------------- 
The CLXDisplay API is the official name for the Qt.pas unit that ships with Kylix 
and also with Delphi6 or later. It acts as an import unit for the Qt widget library 
used by VisualCLX. 
So things in life are a bit more complicated than this. Qt is a C++ class library, 
and OP cannot direct manipulate C++ classes. Because of this, Borland wrote an 
additional library to lay between a CLX application and the Qt library. This extra 
library is called libqtintf.so (the Qt interface library), and Qt.pas is actually 
the import unit for this interface library. 

   TWidgetControl--->Qt.pas->libintf.so--->Qt_Widget_Classes 


Understanding Signal/Slot mechanism 
------------------------------------ 
A hook object is a simple C++ object that exists in the Qt interface library as we 
said as an intermediary. So you want to customise the reaction of a widget like in 
windows with eventhandlers, signal/slot play the role: 
- A signal (event) from a widget 
- A slot (event handler) responds to a signal 

So we learnt, it's not possible to have the slot written directly in OP, means the 
Qt interface library defines a hook class for each widget class. The hook class 
implements a simple slot for each available widget signal, whose sole job is to 
call some code in our Kylix application. 


More on signal / slot and the Way Kylix does: 
--------------------------------------------- 
So it seems that messages (callback functions) are not the CLX way of doing things, 
it means  not that CLX provides no support of messages, but it's not the Kylix way 
of doing things so. We suggest, e.g. mouse movements, that you let CLX respond to 
the mouse and simply override the methods that CLX uses for those events. 
Creating a component and need to catch the mouse messages, you can use the 
following  method: 
10  
11  procedure MouseMove(shift: TShiftState; X, Y: integer); override; 

The way we have to think is that in Qt, developers do not respond directly to 
messages. Instead they work with a signal / slot mechanism and the connect function 
like 
12  
13  QObject::connect(timer, SIGNAL(timeout)), SLOT(timerSlot())); 
14  timer -> start(1000); 

or another example to get acustomed to:   
15  
16  QObject::connect(myslider, SIGNAL(sliderMoved(in )), 
17  mylcdNumber, SLOT(display(in ))); 

There is nothing special about the sliderMoved and display methods. Just ordinary 
C++ methods that are marked as signals and slots, just as some Kylix methods are 
marked as being virtual. 
QObject is the base class in Qt, just as TObject is the base class in OP 
(ObjectPascal).  QObject has a class or static method named connect. An OP class 
method is the same thing as a C++ or Java static method. In particular, you can 
call a class or static method without 
first creating an instance of the object to which it belongs. 

And where's the event-loop in Kylix? 
Here is the event loop that lies at the center of CLX applications: 
procedure TApplication.HandleMessage; 

Hooks again and Overview 
--------------------------- 
Fact: So you learned that Qt uses a signal and slot mechanism, 
and CLX uses an event mechanism. It's not so important how the two are connected, 
it might be  valuable some time later, but here is an overview: 
Qt has a signal and slot mechanism. CLX has an event mechanism. 
To translate Qt signals and  slots into CLX events, the Kylix team created a 
mechanism known as hooks. Each CLX object  type has a hook object. This hook object 
converts the signals and slot events associated with a  particular object into CLX 
events. It then sends these events to the appropriate CLX control. 
In particular, there is a CLX method of TWidgetControl named 
EventFilter that receives the majority of these events. 
You can find more on this topic on the Kylix2 CompanionTool CD: 
sams_publishing/kdgch07.pdf 
chapter 7 CLX architecture & Visual Development or 
Code Central Entry ID #16795 

---------------------------------------------------------------- 
Here an impressive extract: 
If you feel the urge to go beyond the usual CLX 
API, then here is one of the methods that you want to override: 
18  
19  function TWidgetControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; 

This one is the big Kahuna. EventFilter gets most of the events that Qt and the OS 
throws at it. Just opening up QControls and looking at the 500+ lines that form the 
implementation of this method is enough to send any sane programmer running for the 
safety of the standard 
CLX APIs. However, some people like to live on the edge. They claim that the air is 
thinner but cleaner out there. 

20  
21  function TWidgetControl.MainEventFilter(Sender: QObjectH; Event: QEventH): Boolean; 
22  cdecl; 
23  var Form: TCustmForm; 
24  begin 
25    try 
26    if csDesigning in ComponentState  then begin 
27      Form := GetParentForm(Self); 
28      if (Form <> nil) and (Form.DesignerHook <> nil) and 
29      Form.DesignerHook.IsDesignEvent(Self, Sender, Event) then begin 
30        Result := True; 
31        Exit; 
32      end; 
33    end; 
34      Result := EventFilter(Sender, Event); 
35    except 
36      Application.HandleException(Self); 
37      Result := False; 
38    end; 
39  end; 

   

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC