/
/qt.xml
1 <?xml version="1.0"?>
2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
4 <chapter id="qt">
5 <title>Qt</title>
6 <para>
7 Besides the <package>:cl-smoke.qt.gui</package> there are these modules:
8 <itemizedlist>
9 <listitem><para>
10 <package>:cl-smoke.qt.uitools</package>
11 <ulink url="http://doc.trolltech.com/4.5/qtuitools.html">
12 QtUiTools</ulink></para></listitem>
13 <listitem><para><package>:cl-smoke.qt.test</package>
14 <ulink url="http://doc.trolltech.com/4.5/qttest.html">
15 QtTest</ulink></para></listitem>
16 <listitem><para><package>:cl-smoke.qt.webkit</package>
17 <ulink url="http://doc.trolltech.com/4.5/qtwebkit.html">
18 QtWebKit</ulink>
19 </para></listitem>
20 <listitem><para><package>:cl-smoke.qt.phonon</package>
21 <ulink url="http://doc.trolltech.com/4.5/phonon.html">
22 Phonon</ulink>
23 </para></listitem>
24 <listitem><para><package>:cl-smoke.qt.network</package>
25 The network classes of Qt.
26 </para></listitem>
27 <listitem><para><package>:cl-smoke.qt.core</package>
28 the nogui Qt core.
29 </para></listitem>
30 </itemizedlist>
31 which provide bindings for their Qt module. The class names of this modules are in
32 the <package>:qt</package> package. (E.g. Phonon::VideoPlayer is <code>'qt:phonon.video-player</code>
33 and QTest is <code>'qt:test</code>)
34 </para>
35 <para>
36 Additionally there is the <package>:cl-smoke.qt.tests</package> system, containing
37 the unit tests and <package>:cl-smoke.qt.examples</package> for various examples.
38 </para>
39
40 <section id="qapplication"><title>qt:application</title>
41 <para>
42 The <classname>qt:application</classname> object should created with:
43 <macro>qt:with-app</macro>. In its body the event loop can be
44 started with <methodname>qt:exec</methodname>.
45 </para>
46 <example>
47 <title>Hello World</title>
48 <screenshot>
49 <mediaobject>
50 <imageobject>
51 <imagedata fileref="hello-world.png" format="PNG"/>
52 </imageobject>
53 </mediaobject>
54 </screenshot>
55 <programlisting language="lisp">
56 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../qt.examples/src/hello-world.lisp" parse="text" />
57 </programlisting>
58 </example>
59 <para>
60 Subclasses of <classname>qt:paint-device</classname> (e.g. <classname>qt:widget</classname>) can only be used when
61 a <classname>qt:application</classname> instance exists. When there are, for example, <classname>qt:widget</classname> instances
62 at the end of <macro>qt:with-app</macro>, they are deleted by the <classname>qt:application</classname> destructor.
63 </para>
64 <para>
65 Custom <methodname>cxx:paint-event</methodname> methods can use <macro>qt:with-painter</macro>
66 to ensure that the <classname>qt:painter</classname> is deactivated at the end of the method.
67 </para>
68
69 <section><title>Interactive Development</title>
70 <para>
71 The <package>:cl-smoke.repl</package> allows you to start a <classname>qt:application</classname> event loop in the background for
72 interactive development in SLIME.
73 To start the event loop use <methodname>cl-smoke.repl:start-event-loop-in-background</methodname> (or
74 <methodname>cl-smoke.repl:start-event-loop-in-repl</methodname>).
75 <footnote>
76 <para>
77 Currently <code>START-EVENT-LOOP-IN-BACKGROUND</code> is recommended.
78 </para>
79 </footnote>
80 As long as you do not kill the thread or unwind over a foreign function, you should be fine.
81 </para>
82 </section>
83 </section>
84
85 <section id="signal_slot"><title>Signal-Slot</title>
86 <para>
87 <genericfunction>qt:connect</genericfunction> connects a signal to a slot.
88 The signal is either a <classname>qt:qsignal</classname> created with
89 <methodname>qt:make-signal</methodname> or a C++ signal by using
90 <methodname>qt:get-signal</methodname>.
91 The slot can be a slot returned by <classname>qt:make-slot</classname>, a function
92 or a C++ slot a return from <methodname>qt:get-slot</methodname>.
93 </para>
94 <example><title>Quit</title>
95 <programlisting language="lisp">
96 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../qt.examples/src/hello-world-quit.lisp" parse="text" />
97 </programlisting>
98 </example>
99 <para>
100 When the argument types for a slot or signal are not specified they are determined when
101 the first connection is made. Note that when connecting a <classname>qt:qsignal</classname>
102 to a <classname>qt:qslot</classname> at least one must have its arguments types specified. Type specifier <code>T</code>
103 allows to pass a Lisp object as is from a Lisp signal to a Lisp slot.
104 </para>
105
106 <para>
107 The functionality of the Qt <code>SIGNAL</code> and <code>SLOT</code> macros is
108 provided by <methodname>qt:qsignal</methodname> and <methodname>qt:qslot</methodname>.
109 </para>
110 </section>
111
112 <section id="properties"><title>Properties</title>
113 <para>
114 <classname>qt:object</classname> properties can be accessed with
115 <methodname>qt:property</methodname> (setf-able).
116 The name of the property can be either a string in C++ style or a symbol in Lisp style.
117 The predefined Qt properties can be accessed with symbols in the keyword package.
118 </para>
119 <informalexample>
120 <programlisting language="lisp">
121 (let ((object (make-instance '<classname>qt:object</classname>)))
122 (setf (<methodname>qt:property</methodname> object :object-name) "Foo")
123 (assert (string= "Foo" (<methodname>qt:property</methodname> object "objectName"))))
124 </programlisting>
125 </informalexample>
126
127 </section>
128
129 <section id="variant"><title>Variant</title>
130 <para>
131 A <classname>qt:variant</classname> can be constructed with <methodname>qt:make-variant</methodname>
132 or to pass a Lisp object with <methodname>qt:make-lisp-variant</methodname>.
133 Its value is returned by <genericfunction>qt:value</genericfunction>.
134 </para>
135 </section>
136
137 <section id="i18n"><title>i18n</title>
138 <para>
139 You can use <methodname>qt:tr</methodname> to translate strings.
140 </para>
141 <example>
142 <title>i18n Hello World</title>
143 <screenshot>
144 <mediaobject>
145 <imageobject>
146 <imagedata fileref="i18n-hello-world.png" format="PNG"/>
147 </imageobject>
148 </mediaobject>
149 </screenshot>
150
151 <programlisting language="lisp">
152 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
153 href="../qt.examples/src/i18n-hello-world.lisp" parse="text" />
154 </programlisting>
155
156 <formalpara>
157 <title><filename>hello-world_de.po</filename></title>
158 <para>
159 <programlisting language="po">
160 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../qt.examples/src/hello-world_de.po" parse="text" />
161 </programlisting>
162 </para>
163 </formalpara>
164 </example>
165
166 <para>
167 Gettext is used to extract the i18n strings and compile the message catalog.
168 See <filename><ulink url="../qt.examples/src/CMakeLists.txt">CMakeLists.txt</ulink></filename>
169 and <filename><ulink url="../qt.examples/src/UseClQti18n.cmake">UseClQti18n.cmake</ulink></filename>
170 in the <filename class="directory">src/</filename> directory of <package>:cl-smoke.qt.examples</package> on how to do this.
171 </para>
172 </section>
173
174 <section id="qt_examples"><title>Examples</title>
175 <para>
176 You can run the examples with:
177 <programlisting language="lisp">
178 (asdf:oos 'asdf:load-op <package>:cl-smoke.qt.examples</package>)
179 (<methodname>qt.examples:launcher</methodname>)
180 </programlisting>
181 </para>
182
183 <example>
184 <title>Repl</title>
185 <para>
186 Use a <classname>qt:string-list-model</classname> with a <classname>qt:list-view</classname>
187 to show evaluated lisp expressions.
188 </para>
189 <screenshot>
190 <mediaobject>
191 <imageobject>
192 <imagedata fileref="repl.png" format="PNG"/>
193 </imageobject>
194 </mediaobject>
195 </screenshot>
196 <programlisting language="lisp">
197 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../qt.examples/src/repl.lisp" parse="text" />
198 </programlisting>
199 </example>
200
201 <example>
202 <title>Class Browser</title>
203 <para>Qt Classes browser using <package>:cl-smoke.qt.webkit</package> to display the
204 API doc and a custom <classname>qt:list-model</classname>
205 for the <classname>qt:list-view</classname> of the available classes.
206 </para>
207 <screenshot>
208 <mediaobject>
209 <imageobject>
210 <imagedata fileref="class-browser.png" format="PNG"/>
211 </imageobject>
212 </mediaobject>
213 </screenshot>
214 <programlisting language="lisp">
215 <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../qt.examples/src/class-browser.lisp" parse="text" />
216 </programlisting>
217 </example>
218
219 </section>
220
221 <section id="opengl"><title>OpenGL</title>
222 <para>
223 For OpenGL a binding is needed (e.g.:
224 <ulink url="http://common-lisp.net/project/cl-opengl/">cl-opengl</ulink>).
225 </para>
226 <example><title>Origami</title>
227 <para>
228 <ulink url="http://tobias.rautenkranz.ch/darcsweb/darcsweb.cgi?r=cl-smoke/qt.examples;a=tree;f=/src/origami">Origami</ulink>
229 draws a pleated hyperbolic paraboloid using the method described in
230 <ulink url="http://arxiv.org/abs/0906.4747">(Non)existence of Pleated Folds: How Paper Folds Between Creases</ulink>
231 </para>
232 <mediaobject>
233 <videoobject>
234 <videodata fileref='origami.ogg'/>
235 </videoobject>
236 </mediaobject>
237 <para>
238 <note>
239 <para>
240 <ulink url="http://axiom-wiki.newsynthesis.org/FrontPage">Axiom</ulink> is needed to generate the lisp source to that
241 calculates the vertices.
242 </para>
243 </note>
244 </para>
245 </example>
246 </section>
247
248 </chapter>