Sign in Join
Wiki copytemporary

Qt4 binding: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-*(Qt only)*
1+[![Qt logo.svg](https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Qt_logo_2013.svg/60px-Qt_logo_2013.svg.png)](</File:Qt_logo_2013.svg>)
22
3+This article applies to [Qt widgetset](</Category:Qt> "Category:Qt") only.
4+
5+See also: [[Multiplatform Programming Guide]]
6+
37# Download Free Pascal Qt4 Binding
48
5-The binding releases are uploaded to the [FPC Qt4 Binding Home Page](http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html).
9+The binding releases are uploaded to the [FPC Qt4 Binding Home Page](<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html>).
610
711# Install Free Pascal Qt4 Binding
812
9-The download contains a file *README.TXT* which contains the installation instructions.
13+The download contains a file _README.TXT_ which contains the installation instructions.
1014
1115# Links
1216
13-- [Qt Documentation](http://doc.trolltech.com/)
14-- [Pascal Qt4 binding home page](http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html)
15-- [Pascal Qt2/E binding home page](http://users.telenet.be/Jan.Van.hijfte/qtforfpc/qtedemo.html)
16-- [[Qt Interface|Lazarus Qt4 interface]]
17-- [[Qt Interface Mac|Compile instructions for Mac]]
18-- [[Qt4 Maemo Binding|FreePascal Qt4 Binding for Maemo]]
17+ * [Qt Documentation](<http://doc.trolltech.com/>)
18+ * [Pascal Qt4 binding home page](<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html>)
19+ * [Pascal Qt2/E binding home page](<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/qtedemo.html>)
20+ * [[Qt Interface|Lazarus Qt4 interface]]
21+ * [[Qt Interface Mac|Compile instructions for Mac]]
22+ * [[Qt4 Maemo Binding|FreePascal Qt4 Binding for Maemo]]
1923
2024# How to use the Qt4 binding
2125
2226## License
2327
24-Since Qt4 is also available under LGPL, there is no difference in licensing with e.g. Gtk. LGPL allows development of both free and proprietary software without any license fees or royalties. [Nokia Qt License info](http://qt.nokia.com/products/licensing)
28+Since Qt4 is also available under LGPL, there is no difference in licensing with e.g. Gtk. LGPL allows development of both free and proprietary software without any license fees or royalties. [Nokia Qt License info](<http://qt.nokia.com/products/licensing>)
2529
2630## Demo Programs
2731
28-The FPC Qt4 Binding is not meant to create Qt applications in FPC. But it should allow the Lazarus LCL developers to create a Qt Widget set for Lazarus. A Lazarus Qt Widget set allows Lazarus developers to create programs for the entire set of platforms supported by Qt (Windows, Linux, Linux Embedded, OS X, ...). The provided demoes on [FPC Qt4 Binding Home Page](http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html) provide insight in how to use the binding for LCL/Qt development. The lazarus user may however also choose to make some direct Qt4 binding calls to achieve things not yet supported in Lazarus/LCL such as WebKit support.
32+The FPC Qt4 Binding is not meant to create Qt applications in FPC. But it should allow the Lazarus LCL developers to create a Qt Widget set for Lazarus. A Lazarus Qt Widget set allows Lazarus developers to create programs for the entire set of platforms supported by Qt (Windows, Linux, Linux Embedded, OS X, ...). The provided demoes on [FPC Qt4 Binding Home Page](<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/fpcqt4.html>) provide insight in how to use the binding for LCL/Qt development. The lazarus user may however also choose to make some direct Qt4 binding calls to achieve things not yet supported in Lazarus/LCL such as WebKit support.
2933
30-The Qt2 Embedded binding was intended to create full FPC Qt programs and therefore included an extra advanced object oriented layer of Pascal classes and interfaces on top of the Qt classes. [Qt/E demo](http://users.pandora.be/Jan.Van.hijfte/qtforfpc/qtedemo.html). Though this extra layer is convenient, it was chosen not to create one for Qt4 to avoid any performance penalty or code bloat for LCL/Qt.
34+The Qt2 Embedded binding was intended to create full FPC Qt programs and therefore included an extra advanced object oriented layer of Pascal classes and interfaces on top of the Qt classes. [Qt/E demo](<http://users.pandora.be/Jan.Van.hijfte/qtforfpc/qtedemo.html>). Though this extra layer is convenient, it was chosen not to create one for Qt4 to avoid any performance penalty or code bloat for LCL/Qt.
3135
3236## Use the Qt Documentation
3337
3438### How to create a Class
3539
36-Look up the Qt Class you would like to use. Suppose it is [QWidget](http://doc.trolltech.com/4.6/qwidget.html). Some classes provide several constructors (with different parameters). The binding provides for most constructors a corresponding factory function QtClassName_create(parameters). Store the class in a variable of type QtClassName+H. The beginning of Qt4.pas provides you with a list of all supported classes. That same list also serves to provide type safe usage of the Qt class handles. The list encodes the Class hierarchy.
37-
38-``` pascal
39- var W : QWidgetH;
40- ...
41- W := QWidget_create(nil,0);
42-
40+Look up the Qt Class you would like to use. Suppose it is [QWidget](<http://doc.trolltech.com/4.6/qwidget.html>). Some classes provide several constructors (with different parameters). The binding provides for most constructors a corresponding factory function QtClassName_create(parameters). Store the class in a variable of type QtClassName+H. The beginning of Qt4.pas provides you with a list of all supported classes. That same list also serves to provide type safe usage of the Qt class handles. The list encodes the Class hierarchy.
4341```
42+var W : QWidgetH;
43+ ...
44+ W := QWidget_create(nil,0);
45+```
4446
4547### How to call a method of a Qt Class
4648
47-Use the Nokia Qt documentaton to find out how and when to use which method. Suppose you want to use [void QWidget::setFixedHeight ( int h )](http://doc.trolltech.com/4.5/qwidget.html#setFixedHeight) The corresponding Pascal fuction will be ClassName+_+MethodName. So look in Qt4.pas for the definition of QWidget_setFixedHeight
48-
49-``` pascal
50- procedure QWidget_setFixedHeight(handle: QWidgetH; h: Integer);
51-
49+Use the Nokia Qt documentaton to find out how and when to use which method. Suppose you want to use [void QWidget::setFixedHeight ( int h )](<http://doc.trolltech.com/4.5/qwidget.html#setFixedHeight>) The corresponding Pascal fuction will be ClassName+_+MethodName. So look in Qt4.pas for the definition of QWidget_setFixedHeight
5250```
53-
54-Note how the pascal function has an additional parameter: the Qt Class instance handle of your QWidget Class. Calling the setFixedHeight method will be like this
51+procedure QWidget_setFixedHeight(handle: QWidgetH; h: Integer);
52+```
5553
56-``` pascal
57- QWidget_ setFixedHeight(W,100);
58-
54+Note how the pascal function has an additional parameter: the Qt Class instance handle of your QWidget Class. Calling the setFixedHeight method will be like this
5955```
56+QWidget_ setFixedHeight(W,100);
57+```
6058
6159### How to hook a Pascal Method to a signal of a Qt Class
6260
63-Qt classes can emit signals and other classes can hook method (slots) to these signals. The binding allows to hook Pascal methods to the Qt classes. To be able to do this, an intermediate Qt class needs to be created. For every class that emits signals, that intermediate class, referred to as hook, is provided in the binding and is called ClassName_hookH. This class can connect to all signals of its corresponding class and will call the corresponding pascal method upon occurrence of the signal.
64-
65-Example: The Qt Class QAbstractButton has a [signal clicked](http://doc.trolltech.com/4.5/qabstractbutton.html#clicked). The hook class of the binding is QAbstractButton_hookH.
61+Qt classes can emit signals and other classes can hook method (slots) to these signals. The binding allows to hook Pascal methods to the Qt classes. To be able to do this, an intermediate Qt class needs to be created. For every class that emits signals, that intermediate class, referred to as hook, is provided in the binding and is called ClassName_hookH. This class can connect to all signals of its corresponding class and will call the corresponding pascal method upon occurrence of the signal.
6662
67-``` pascal
68- var
69- hook : QAbstractButton_hookH;
70- ...
71- hook:=QAbstractButton_hook_create(AbstractButtonHandle);
72- QAbstractButton_hook_hook_clicked(hook, @Clicked);
73-
63+Example: The Qt Class QAbstractButton has a [signal clicked](<http://doc.trolltech.com/4.5/qabstractbutton.html#clicked>). The hook class of the binding is QAbstractButton_hookH.
7464```
75-
76-The definition of hook_hook_clicked shows the type of the Pascal Method to provide:
77-
78-``` pascal
79- procedure QAbstractButton_hook_hook_clicked(handle: QAbstractButton_hookH; hook: QAbstractButton_clicked_Event);
80-
65+var
66+ hook : QAbstractButton_hookH;
67+ ...
68+ hook:=QAbstractButton_hook_create(AbstractButtonHandle);
69+ QAbstractButton_hook_hook_clicked(hook, @Clicked);
8170```
8271
83-That Pascal Method type is defined as:
84-
85-``` pascal
86- type
87- QAbstractButton_clicked_Event = procedure (checked: Boolean = False) of object '''cdecl''';
88-
72+The definition of hook_hook_clicked shows the type of the Pascal Method to provide:
8973```
74+procedure QAbstractButton_hook_hook_clicked(handle: QAbstractButton_hookH; hook: QAbstractButton_clicked_Event);
75+```
9076
91-Therefore the method Clicked should be defined as: (**Take note of the cdecl calling convention**)
77+That Pascal Method type is defined as:
78+```
79+type
80+ QAbstractButton_clicked_Event = procedure (checked: Boolean = False) of object '''cdecl''';
81+```
9282
93-``` pascal
94- TButton = class (TObject)
95- ...
96- procedure Clicked(checked: Boolean);'''cdecl''';
97- ...
98- procedure TButton.Clicked(checked: Boolean = False);'''cdecl''';
99- begin
100- end;
101-
83+Therefore the method Clicked should be defined as: (**Take note of the cdecl calling convention**)
10284```
85+TButton = class (TObject)
86+ ...
87+ procedure Clicked(checked: Boolean);'''cdecl''';
88+ ...
89+ procedure TButton.Clicked(checked: Boolean = False);'''cdecl''';
90+ begin
91+ end;
92+```
10393
10494### C++ Multiple inheritance
10595
106-Some Qt Classes inherit from more than 1 class. QWidget inherits from QObject and QPaintDevice. When you create in C++ a QWidget instance, there are actually two instances that get created. One instance handle for QObject and one for QPaintDevice. In the binding, the returned handle will be for the first parent (QObject). To use the methods provided through inheritance by the second parent, you need to use the second instance handle. That second instance handle is obtained by using a function called FirstClass_To_SecondClass:
107-
108-``` pascal
109- function QWidget_to_QPaintDevice(handle: QWidgetH): QPaintDeviceH;
110-
96+Some Qt Classes inherit from more than 1 class. QWidget inherits from QObject and QPaintDevice. When you create in C++ a QWidget instance, there are actually two instances that get created. One instance handle for QObject and one for QPaintDevice. In the binding, the returned handle will be for the first parent (QObject). To use the methods provided through inheritance by the second parent, you need to use the second instance handle. That second instance handle is obtained by using a function called FirstClass_To_SecondClass:
11197```
112-
113-In the demo program you notice how the paint event is used to paint on a QWidget. To paint, you need to create a QPainter (like canvas) from the QWidget. The Qt documentation shows that the constructor of QPainter requires a QPaintDevice. So here is an extract of the demo
98+function QWidget_to_QPaintDevice(handle: QWidgetH): QPaintDeviceH;
99+```
114100
115-``` pascal
116- var PaintBox : QWidgetH;
117- PaintBox:=QWidget_create();
118- ...
119- // In the paint method
120- var CV : QPainterH;
121- CV:=QPainter_create(QWidget_to_QPaintDevice(PaintBox));
122-
101+In the demo program you notice how the paint event is used to paint on a QWidget. To paint, you need to create a QPainter (like canvas) from the QWidget. The Qt documentation shows that the constructor of QPainter requires a QPaintDevice. So here is an extract of the demo
123102```
103+var PaintBox : QWidgetH;
104+ PaintBox:=QWidget_create();
105+ ...
106+ // In the paint method
107+ var CV : QPainterH;
108+ CV:=QPainter_create(QWidget_to_QPaintDevice(PaintBox));
109+```
124110
125-Do not use typecasting like QPaintDeviceH(PaintBox). The compiler would complain if you did this anyhow. See type safety below.
111+Do not use typecasting like QPaintDeviceH(PaintBox). The compiler would complain if you did this anyhow. See type safety below.
126112
127113# Technical information
128114
129115## Supported Platforms
130116
131-The Qt library works on different platforms such as Linux/BSD, Windows, OS X and Embedded. Depending of the platform a number of methods are available or not.
132-
133-Example functions:
134-
135-- Windows only function: QPixmap_toWinHBITMAP
136-- Linux only function: QApplication_x11EventFilter
137-- macOS only function: QApplication_macEventFilter
138-- Embedded only function: QApplication_qwsEventFilter
139-
140-Qt achieves this with conditional defines such as Q_WS_MAC or Q_WS_QWS. There are many more Q_XXX that allow to fine tune the Qt library for many platforms. You can e.g. configure Qt to not include CUPS support with QT_NO_CUPS. The Qt library source that is contained in the Windows Qt Download or the Embedded download is pretty similar, only very platform specific include files are omitted. The key difference is that the config files are different, e.g. in qconfig.h Q_WS_QWS is enabled in the Embedded Qt Download and not in the qconfig.h from other Platform downloads
117+The Qt library works on different platforms such as Linux/BSD, Windows, OS X and Embedded. Depending of the platform a number of methods are available or not.
141118
142-The pascal Qt interface library also uses a single source for all platforms by using conditional defines. Not as many defines as in Qt are used, the sole aim was to cope with the different platforms: Linux, Windows, OS X and Embedded.
119+Example functions:
143120
144-This is achieved by defining for a given platform a number of QT_XXX defines and then converting the headers with moc. Moc allows the provision of defines so that the methods that are available when these defines are set, are the only ones visible.
121+ * Windows only function: QPixmap_toWinHBITMAP
122+ * Linux only function: QApplication_x11EventFilter
123+ * macOS only function: QApplication_macEventFilter
124+ * Embedded only function: QApplication_qwsEventFilter
145125
146-The different binding platform defines are:
126+Qt achieves this with conditional defines such as Q_WS_MAC or Q_WS_QWS. There are many more Q_XXX that allow to fine tune the Qt library for many platforms. You can e.g. configure Qt to not include CUPS support with QT_NO_CUPS. The Qt library source that is contained in the Windows Qt Download or the Embedded download is pretty similar, only very platform specific include files are omitted. The key difference is that the config files are different, e.g. in qconfig.h Q_WS_QWS is enabled in the Embedded Qt Download and not in the qconfig.h from other Platform downloads
147127
148-| Platform define | List of Qt defines |
149-|-----------------|----------------------------------------------------|
150-| BINUX | Q_WS_X11 Q_OS_LINUX Q_OS_UNIX |
151-| MSWINDOWS | Q_WS_WIN |
152-| DARWIN | Q_WS_MAC Q_OS_UNIX |
153-| QTOPIA | Q_WS_QWS Q_OS_LINUX Q_OS_UNIX QT_NO_SESSIONMANAGER |
128+The pascal Qt interface library also uses a single source for all platforms by using conditional defines. Not as many defines as in Qt are used, the sole aim was to cope with the different platforms: Linux, Windows, OS X and Embedded.
154129
155-Platforms
130+This is achieved by defining for a given platform a number of QT_XXX defines and then converting the headers with moc. Moc allows the provision of defines so that the methods that are available when these defines are set, are the only ones visible.
156131
157-Binux stands for BSD/Linux.
132+The different binding platform defines are:
158133
159-The binding consists of a C++ part, that uses above defines to enclose platform specific methods. To compile the code on a given platform, the respective define should be set. In the V1.X versions, the platform specific compile scripts defined the appropriate platform, in the V2.X the provided qmake project automatically sets the proper platform define.
134+Platforms Platform define | List of Qt defines
135+---|---
136+BINUX | Q_WS_X11 Q_OS_LINUX Q_OS_UNIX
137+MSWINDOWS | Q_WS_WIN
138+DARWIN | Q_WS_MAC Q_OS_UNIX
139+QTOPIA | Q_WS_QWS Q_OS_LINUX Q_OS_UNIX QT_NO_SESSIONMANAGER
140+
141+Binux stands for BSD/Linux.
160142
161-The binding also consists of a pascal part. In that part the different defines are enabled by using the free pascal predefined defines or they just are the same.
143+The binding consists of a C++ part, that uses above defines to enclose platform specific methods. To compile the code on a given platform, the respective define should be set. In the V1.X versions, the platform specific compile scripts defined the appropriate platform, in the V2.X the provided qmake project automatically sets the proper platform define.
162144
163-Note that embedded is a special platform, that is both linux and embedded. (I did not look into the recently created wince and symbian qt variant yet). But to avoid the inclusion of any missing X11 libraries, you should not define BINUX for the compilation of the library or qt4.pas. The V1.X library source package for Linux contains 2 compile scripts, one for linux (compile_lib.sh) that defines BINUX and one for Qt/Embedded (compile_lib_qtopia.sh) that defines QTOPIA and allows calling either gcc (intel qvfb) or arm-linux-gcc (arm embedded). In the V2.X bindings, you need to set QTOPIA yourself in the qmake project.
145+The binding also consists of a pascal part. In that part the different defines are enabled by using the free pascal predefined defines or they just are the same.
164146
165-The lazarus lcl qt interface, also uses platform specific defines in the lcl code that calls the Qt binding. To correctly compile the lcl for embedded, you need to set the define QTOPIA. The other used defines (LINUX, WINDOWS, DARWIN=macOS) are done automatically by using existing platform specific defines provided by fpc.
147+Note that embedded is a special platform, that is both linux and embedded. (I did not look into the recently created wince and symbian qt variant yet). But to avoid the inclusion of any missing X11 libraries, you should not define BINUX for the compilation of the library or qt4.pas. The V1.X library source package for Linux contains 2 compile scripts, one for linux (compile_lib.sh) that defines BINUX and one for Qt/Embedded (compile_lib_qtopia.sh) that defines QTOPIA and allows calling either gcc (intel qvfb) or arm-linux-gcc (arm embedded). In the V2.X bindings, you need to set QTOPIA yourself in the qmake project.
166148
167-To compile lazarus for embedded/qtopia:
149+The lazarus lcl qt interface, also uses platform specific defines in the lcl code that calls the Qt binding. To correctly compile the lcl for embedded, you need to set the define QTOPIA. The other used defines (LINUX, WINDOWS, DARWIN=macOS) are done automatically by using existing platform specific defines provided by fpc.
168150
169-```text
170- make PREFIX=/usr clean all LCL_PLATFORM=qt OPT="-dQTOPIA"
151+
152+To compile lazarus for embedded/qtopia:
171153```
154+make PREFIX=/usr clean all LCL_PLATFORM=qt OPT="-dQTOPIA"
155+```
172156
173-<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/Lazarus_Embedded.png> last Version verified to work is 0.9.29
157+<http://users.telenet.be/Jan.Van.hijfte/qtforfpc/Lazarus_Embedded.png> last Version verified to work is 0.9.29
174158
175159## Type safe Qt Class Handles
176160
177-In Qt4.pas you will see a large list of type definitions of Qt Class handles.
178-
179-``` pascal
180- QWidgetH = class(QObjectH) end;
181- QAbstractButtonH = class(QWidgetH) end;
182- QPushButtonH = class(QAbstractButtonH) end;
183-
161+In Qt4.pas you will see a large list of type definitions of Qt Class handles.
184162```
163+QWidgetH = class(QObjectH) end;
164+ QAbstractButtonH = class(QWidgetH) end;
165+ QPushButtonH = class(QAbstractButtonH) end;
166+```
185167
186-This list ensures type safety and encodes the class hierarchy.
168+This list ensures type safety and encodes the class hierarchy.
187169
188170### Inheritance
189171
190-This way you can call an inherited function using a descendant class type. The extract of the list shows that QPushButton descends from QWidget, so you can call the inherited method "width" from QWidget with your QPushButton handle
191-
192-``` pascal
193- var Btn : QPushButtonH;
194- ...
195- Btn := QPushButton_create(parent);
196- writeln('Button Width:',QWidget_width(Btn));
197-
172+This way you can call an inherited function using a descendant class type. The extract of the list shows that QPushButton descends from QWidget, so you can call the inherited method "width" from QWidget with your QPushButton handle
198173```
174+var Btn : QPushButtonH;
175+ ...
176+ Btn := QPushButton_create(parent);
177+ writeln('Button Width:',QWidget_width(Btn));
178+```
199179
200180### Type Safe Class Parameters
201181
202-In the Multiple inheritance paragraph, you have seen that you need to call a convert function to convert your QWidget to a QPaintDevice. If you didn't use the convert the compiler would complain. Suppose we omit the convert function
203-
204-``` pascal
205-
206- // Do not do this !!!
207- CV:=QPainter_create(PaintBox);
208-
182+In the Multiple inheritance paragraph, you have seen that you need to call a convert function to convert your QWidget to a QPaintDevice. If you didn't use the convert the compiler would complain. Suppose we omit the convert function
209183```
210-
211-The type safety net will make the compiler complain like this:
184+// Do not do this !!!
185+ CV:=QPainter_create(PaintBox);
186+```
212187
213-``` pascal
188+The type safety net will make the compiler complain like this:
189+```
214190demo.pas(265,30) Error: Incompatible type for arg no. 1: Got "QWidgetH", expected "QPaintDeviceH"
215191```
216192
217-Similar if you would not use the convert function, but would just use typecast like this
218-
219-``` pascal
220- // Do '''not''' do this !!!
221- CV:=QPainter_create(QPaintDeviceH(PaintBox));
222-
193+Similar if you would not use the convert function, but would just use typecast like this
223194```
224-
225-The compiler will complain with:
195+// Do '''not''' do this !!!
196+ CV:=QPainter_create(QPaintDeviceH(PaintBox));
197+```
226198
227-```text
199+The compiler will complain with:
200+```
228201demo.pas(266,21) Warning: Class types "QWidgetH" and "QPaintDeviceH" are not related
229202```
230203
231-That typecast would not change the handle. Handles are just numbers, the returned handle/number of QWidget_to_QPaintDevice is different than the PaintBox handle/number. It indirectly points to a different Virtual Method Table.
204+That typecast would not change the handle. Handles are just numbers, the returned handle/number of QWidget_to_QPaintDevice is different than the PaintBox handle/number. It indirectly points to a different Virtual Method Table.
232205
233206### Type Safe Method Parameters
234207
235-The Pascal methods that can be provided to the Hook classes, need to be of the correct function type. This prevents otherwise not so pleasant stack problems when the binding c++ code calls the provided pascal method.
208+The Pascal methods that can be provided to the Hook classes, need to be of the correct function type. This prevents otherwise not so pleasant stack problems when the binding c++ code calls the provided pascal method.
236209
237210## Qt Enums and QFlags
238211
239-Qt uses a template class QFlags\<Enum\> when passing combinations of an Enum to a method. This Qt Doc [WindowType](http://doc.trolltech.com/4.5/qt.html#WindowType-enum) defines the enum Qt::WindowType and the associated Qt Class Qt::WindowFlags. In the header file the flags are declared like this
240-
241-``` cpp
242- Q_DECLARE_FLAGS(WindowFlags, WindowType)
243-
212+Qt uses a template class QFlags<Enum> when passing combinations of an Enum to a method. This Qt Doc [WindowType](<http://doc.trolltech.com/4.5/qt.html#WindowType-enum>) defines the enum Qt::WindowType and the associated Qt Class Qt::WindowFlags. In the header file the flags are declared like this
244213```
245-
246-More about this macro: [Q_DECLARE_FLAGS](http://doc.trolltech.com/4.4/qflags.html#Q_DECLARE_FLAGS)
214+Q_DECLARE_FLAGS(WindowFlags, WindowType)
215+```
247216
248-Alot of methods have a QFlags Qt Class as a parameter. Normally we would need to create a instance of this class, pass it to the method and delete it ourselves in the pascal code. To avoid all this hassle the binding generator changed all methods to allow for passing a pascal cardinal type.
217+More about this macro: [Q_DECLARE_FLAGS](<http://doc.trolltech.com/4.4/qflags.html#Q_DECLARE_FLAGS>)
249218
250-Let's sample this with the following constructor [QMainWindow](http://doc.trolltech.com/4.0/qmainwindow.html#QMainWindow). The constructor needs the QFlags Qt::WFlags. The Qt doc shows that this is just a synonym for Qt::WindowFlags. The following Qt4.pas extract show that the enums are declared as cardinals, so that "or" combination are allowed ("or" on pascal enums is not allowed). Sometimes these enums are used as default value of a parameter in a function. As pascal does not allow typed constants in default values, the different values of the enums are declared as untyped constants. The corresponding QFlags\<\> type is simply redeclared as the same type as the enum. Its name and the comments allow for easy cross reference Qt4.pas and the Qt documentation.
219+Alot of methods have a QFlags Qt Class as a parameter. Normally we would need to create a instance of this class, pass it to the method and delete it ourselves in the pascal code. To avoid all this hassle the binding generator changed all methods to allow for passing a pascal cardinal type.
251220
252-``` pascal
253- type
254- QtWindowType = cardinal; // Qt::WindowType (4)
255- QtWindowFlags = QtWindowType; // QFlags<>
256- const
257- QtWidget = 0 { $0 };
258- QtWindow = 1 { $1 };
259- QtDialog = 3 { $3 };
260- ... etc
261-
221+Let's sample this with the following constructor [QMainWindow](<http://doc.trolltech.com/4.0/qmainwindow.html#QMainWindow>). The constructor needs the QFlags Qt::WFlags. The Qt doc shows that this is just a synonym for Qt::WindowFlags. The following Qt4.pas extract show that the enums are declared as cardinals, so that "or" combination are allowed ("or" on pascal enums is not allowed). Sometimes these enums are used as default value of a parameter in a function. As pascal does not allow typed constants in default values, the different values of the enums are declared as untyped constants. The corresponding QFlags<> type is simply redeclared as the same type as the enum. Its name and the comments allow for easy cross reference Qt4.pas and the Qt documentation.
262222```
263-
264-Now lets use this on QMainWindow. The following code creates a MainWindow that stays on top and has a small toolwindow title bar:
223+type
224+ QtWindowType = cardinal; // Qt::WindowType (4)
225+ QtWindowFlags = QtWindowType; // QFlags<>
226+ const
227+ QtWidget = 0 { $0 };
228+ QtWindow = 1 { $1 };
229+ QtDialog = 3 { $3 };
230+ ... etc
231+```
265232
266-``` pascal
267- MainWindow:=QMainWindow_create(nil,QtTool or QtWindowStaysOnTopHint);
268-
233+Now lets use this on QMainWindow. The following code creates a MainWindow that stays on top and has a small toolwindow title bar:
269234```
235+MainWindow:=QMainWindow_create(nil,QtTool or QtWindowStaysOnTopHint);
236+```
270237
271238## Floating Point Exceptions
272239
273-Throughout the Qt-library, Trolltech does not check for divisions by zero for floating points. No exceptions are generated because FPEs (Floating Point Exceptions) have been disabled. However when you link an FPC program to a library, FPC re-enables FPEs. To solve this the call fedisableexcept(FE_ALL_EXCEPT) was added to Qt4.pas. Otherwise several graphic painting calls would cause exceptions.
274-
275-E.g. a call to QPainter::drawLine() will ultimately lead to a call to qt_tesselate_polygon in qpaintengine_x11.cpp where a division by zero will lead to an exception in the line:
240+Throughout the Qt-library, Trolltech does not check for divisions by zero for floating points. No exceptions are generated because FPEs (Floating Point Exceptions) have been disabled. However when you link an FPC program to a library, FPC re-enables FPEs. To solve this the call fedisableexcept(FE_ALL_EXCEPT) was added to Qt4.pas. Otherwise several graphic painting calls would cause exceptions.
276241
277-``` cpp
278- edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative
279-
242+E.g. a call to QPainter::drawLine() will ultimately lead to a call to qt_tesselate_polygon in qpaintengine_x11.cpp where a division by zero will lead to an exception in the line:
280243```
244+edge.m = (p1.y() - p2.y()) / (p1.x() - p2.x()); // line derivative
245+```
281246
282247## Pascalify Qt Classes
283248
284249### What is the problem
285250
286-The binding allows you to create Qt classes by reference but not by value. Assignment of one Qt class by value to another is impossible, because the pascal compiler does not know the interior of a C++ Qt Class. As this may not be clear, let us make an example.
251+The binding allows you to create Qt classes by reference but not by value. Assignment of one Qt class by value to another is impossible, because the pascal compiler does not know the interior of a C++ Qt Class. As this may not be clear, let us make an example.
287252
288253### Example of the problem
289254
290-In C++ you can write:
291-
292-``` cpp
293- QColor hourColor(127, 0, 127);
294- painter.setBrush(hourColor)
295-
255+In C++ you can write:
296256```
297-
298-At the end of this procedure you do not have to delete the QColor instance. The binding without pascalify of QColor would force you to write:
257+QColor hourColor(127, 0, 127);
258+ painter.setBrush(hourColor)
259+```
299260
300-``` pascal
301- var hourColor : QColorH;//*QColor
302- hourColor:=QColor_create(127,0,127); //new QColor()
303- brush:=QBruh_create(hourColor);
304- QColor_destroy(hourColor)
305-
261+At the end of this procedure you do not have to delete the QColor instance. The binding without pascalify of QColor would force you to write:
306262```
263+var hourColor : QColorH;//*QColor
264+ hourColor:=QColor_create(127,0,127); //new QColor()
265+ brush:=QBruh_create(hourColor);
266+ QColor_destroy(hourColor)
267+```
307268
308-The destroy is rather annoying for small classes like QRect and QColor.
269+The destroy is rather annoying for small classes like QRect and QColor.
309270
310271### Solution:Pascalify
311272
312-Pascalify means the creation of a pascal record that is binary compatible with the Qt class. Qt classes without a VMT like QColor, QRect or QRectF are easy targets. If you provide a pointer to this record, the C++ compiler will not notice the difference. So now you can simply write
313-
314-``` pascal
315- var HourColor : TQColor;// a pascal record type compatible with QColor
316- QColor_fromRGB(@hourColor,127,0,127);
317- brush:=QBrush_create(@hourColor);
273+Pascalify means the creation of a pascal record that is binary compatible with the Qt class. Qt classes without a VMT like QColor, QRect or QRectF are easy targets. If you provide a pointer to this record, the C++ compiler will not notice the difference. So now you can simply write
318274```
319-
320-Now you do not need to free the QColor so there is less chance for a memory leak.
275+var HourColor : TQColor;// a pascal record type compatible with QColor
276+ QColor_fromRGB(@hourColor,127,0,127);
277+ brush:=QBrush_create(@hourColor);
278+```
321279
322-Note: QRect and PRect use the same trick but with some extra adjustments for two reasons:
280+Now you do not need to free the QColor so there is less chance for a memory leak.
323281
324-```text
282+Note: QRect and PRect use the same trick but with some extra adjustments for two reasons:
283+```
325284* In macOS the layout of QRect is different than the layout of TRect in pascal.
326-* The TRect definition of LCL is different from Qt, with respect to the inclusion of the right and bottom line.
285+ * The TRect definition of LCL is different from Qt, with respect to the inclusion of the right and bottom line.
327286```
328287
329-The interface adjust with +1 when going to Qt or with -1 when going to Pascal.
330-
331-Internal code sample for clarity:
288+The interface adjust with +1 when going to Qt or with -1 when going to Pascal.
332289
333-``` cpp
334- inline void copyPRectToQRect(PRect pr, QRect &qr)
335- {
336- #if defined DARWIN
337- qr.setLeft(((QRect *)pr)->top());
338- qr.setTop(((QRect *)pr)->left());
339- qr.setRight(((QRect *)pr)->bottom()-1);
340- qr.setBottom(((QRect *)pr)->right()-1);
341- #else
342- qr.setLeft(((QRect *)pr)->left());
343- qr.setTop(((QRect *)pr)->top());
344- qr.setRight(((QRect *)pr)->right()-1);
345- qr.setBottom(((QRect *)pr)->bottom()-1);
346- #endif
347- }
290+Internal code sample for clarity:
348291```
292+inline void copyPRectToQRect(PRect pr, QRect &qr)
293+ {
294+ #if defined DARWIN
295+ qr.setLeft(((QRect *)pr)->top());
296+ qr.setTop(((QRect *)pr)->left());
297+ qr.setRight(((QRect *)pr)->bottom()-1);
298+ qr.setBottom(((QRect *)pr)->right()-1);
299+ #else
300+ qr.setLeft(((QRect *)pr)->left());
301+ qr.setTop(((QRect *)pr)->top());
302+ qr.setRight(((QRect *)pr)->right()-1);
303+ qr.setBottom(((QRect *)pr)->bottom()-1);
304+ #endif
305+ }
306+```
349307
350308# FAQ
351309
352310## I get linker error /usr/bin/ld: cannot find -lQt4Pas
353311
354312The Qt4Pas comes with a library (e.g. under Linux libqt4.so) which must be installed. See installation.
355313
356314---
357-*From the Free Pascal wiki, page "Qt4 binding", as it stood on 2020-02-23 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
358-Category: Interfaces
359-Category: Qt
315+*From the Free Pascal wiki, page "Qt4 binding", as the Internet Archive kept it on 2026-01-11, last changed on 2020-02-24. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history