chickadee » qt

Outdated egg!

This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.

If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.

qt

Introduction

This extension provides an easy to use interface to Trolltech's Qt 4 toolkit. It provides bindings for the GUI side of Qt, as well as for Qt's builtin networking and dbus libraries. A great way to get started with using this API is to check out the unit tests bundled with this egg, in tests.scm. They provide an example of many of the API calls described here and all of the more complex ones.

Memory management is completely manual (with the exception of child widgets, which are deleted when their parent is). To release the resources of a widget or other Qt objects, call qt:delete.

This Qt binding is necessarily incomplete since Qt is huge and testing every feature after adding it in would be too time consuming. If you miss certain functionality like widget-specific operations, contact the author. Most operations just need trivial 1 line changes to add.

Installation

The QTDIR environment variable must be set to the installation directory of Qt, like this:

QTDIR=/usr/local/Trolltech/Qt-4.2.0 chicken-install qt

Windows

This extension has been tested with the binary distribution of Qt, based on the mingw compiler included in the Qt distribution. It is recommended to use a custom build of CHICKEN that uses this particular gcc version and which is installed directly in the Qt installation directory. So assuming Qt is installed in `c:\Qt\2010.01`, do the following:

 <obtain chicken sources, and cd to that directory>
 
 c:\tmp\chicken> mingw32-make PREFIX=c:/Qt/2010.01 PLATFORM=mingw
 c:\tmp\chicken> mingw32-make PREFIX=c:/Qt/2010.01 PLATFORM=mingw install
 c:\tmp\chicken> chicken-install qt

Note that the author does not have a copy of Windows and as such will not provide any Windows support.

N900

This extension is known to work on at least one embedded device, the Nokia n900. More specific information is available here.

Classes

The following protobj classes are exposed:

<qt>
 <qt-action>
 <qt-dbus-connection>
 <qt-http>
 <qt-object>
  <at-application>
  <qt-widget>
   <qt-text-edit>
  <qt-receiver>
  <qt-timer>
  <qt-sound>
 <qt-pixmap>
 <qt-variant-list>

General

The basic mode of operation is that you create your UI using the qt designer, few bindings currently exist for creating widgets, and export them as an xml file. This file can then be read in to set up windows and widgets. By not having bindings for the widget creation routines we keep this egg at a manageable size, and the qt designer seems to be the best way to use Qt4 anyway. Widgets that must be created on the fly do have bindings.

qt:init

qt:initprocedure

Initializes Qt (including any command-line processing) and returns the application object, an instance of <qt-application>. Performs an implicit

(qt:connect <application> "lastWindowClosed()" <application> "quit()")

qt:run

qt:run #!optional ONCEprocedure

Runs the Qt event loop. If ONCE is given and true, then the procedure returns once all pending events have been processed (use (qt:run #t) in a loop when you want to do some custom idle processing, for example).

Widgets

qt:widget

qt:widget UIXML #!optional PARENTprocedure

Parses the UI description in the string UIXML, which should be the XML representation of a user interface created by the Qt designer application. Returns an instance of <qt-widget>, the toplevel widget. If PARENT is given, the newly created widget will be a child of this.

qt:delete

qt:delete OBJECTprocedure

Deletes OBJECT, which should be an instance of <qt-object> or <qt-pixmap>.

qt:show

qt:show WIDGETprocedure

Shows the given widget.

qt:hide

qt:hide WIDGETprocedure

Hides the widget from view.

qt:find

qt:find WIDGET NAMEprocedure

Returns the direct or indirect child widget of WIDGET named NAME (a string) or #f if no such child widget could be found.

qt:pixmap

qt:pixmap FILENAMEprocedure

Loads an image file and returns an instance of <qt-image>.

qt:update

qt:update WIDGETprocedure

Schedules a repaint event for the given widget.

Properties

qt:property

qt:property WIDGET PROPprocedure
 (set! (qt:property WIDGET PROP) VALUE)

Get or set a widget property with the name PROP (a string or symbol). See the Qt documentation for more information about which widget supports which properties. Value conversion is automatically, the following value types are supported:

Property (C++) type    Scheme type
QString                string
int                    integer
double                 number
bool                   boolean
char                   char
QPixmap                <qt-image>
Point                  s32vector
Size                   s32vector
Rect                   s32vector
PointF                 f64vector
SizeF                  f64vector
RectF                  f64vector

Signals and receivers

qt:receiver

qt:receiver THUNKprocedure

Returns an instance of <qt-receiver> that when connected to a Qt signal will invoke PROC once the signal is emitted.

qt:connect

qt:connect SOURCE SIGNAL DESTINATION #!optional SLOTprocedure

Connects the signal SIGNAL from the <qt-object> SOURCE to the slot SLOT from DESTINATION. If no slot is given then slot will have the same signature and name as the SIGNAL. Signals and slots should be strings and follow the normal syntax used by Qt. DESTINATION can be a <qt-object> or a scheme function. SLOT can have any number of arguments as long as they can be marshalled back to scheme, the types currently are: int, string, bool, uint and double. Dispatch is handled entirely by Qt using a fake object per call to qt:connect meaning that all of the rules for matching types and numbers of arguments still apply. Returns a procedure that disconnects and frees the memory used by this connection.

qt:emit-signal

qt:emit-signal OBJECT SLOT #!rest ARGUMENTSprocedure

Emit a signal to an object with any number of arguments.

qt:invoke-method

(qt:invoke-method OBJECT SLOT [RESULT?] . ARGUMENTS)procedure

Emit a signal to an object, if a RESULT? is true then the return value of the invoked singal will be returned.

Timers

qt:timer

qt:timer SECONDSprocedure

Creates and returns a timer object which can be connected to a receiver and which will emit "timeout()" signals every SECONDS.

qt:start

qt:start TIMERprocedure

Starts the given timer.

qt:stop

qt:stop TIMERprocedure

Stops the given timer.

Lists

qt:clear

qt:clear WIDGETprocedure

Clears all entries from WIDGET which should be a QListWidget.

qt:add

qt:add WIDGET STRINGprocedure

Adds a new entry to a QListWidget, QComboBox or QTreeWidget. In the latter case, the columns should be separated by the | character (vertical bar).

qt:item

qt:item WIDGET INDEXprocedure

Returns the text of the QListWidget item with the given index.

qt:set-headers

qt:set-headers WIDGET STRINGprocedure

Sets the column headers in a QTreeWidget. Columns should be separated by the | character (vertical bar).

Text edit widgets

qt:selection

qt:selection TEXTEDITprocedure

Returns the text of the currently active selection, or the empty string, if no text is selected.

qt:insert

qt:insert TEXTEDIT STRINGprocedure

Inserts STRING at the current cursor location.

Dialogs

qt:message

qt:message TEXT #!key caption parent button1 button2 button3procedure

Opens a QMessageBox with the given properties and returns the index of the pressed button.

qt:get-open-filename CAPTION DIRECTORY #!key parent options filterprocedure

Shows a modal file-selection dialog and returns the selected filename (or "", if the dialog was canceled). options should be a list with zero or more of the following keywords:

#:show-dirs-only
#:dont-resolve-symlinks
#:dont-confirm-overwrites
#:dont-use-sheet
#:dont-use-native-dialog
qt:get-save-filename CAPTION DIRECTORY #!key parent options filterprocedure

Shows a modal file-selection for saving.

qt:get-directory CAPTION DIRECTORY #!key parent options filterprocedure

Shows a modal directory-selection dialog.

Sound

qt:sound

qt:sound FILENAMEprocedure

Loads a sound-file and returns an instance of <qt-sound>.

qt:play

qt:play SOUNDprocedure

Plays the sound asynchronously.

qt:stop

qt:stop SOUNDprocedure

Stops a currently playing sound.

Global keyboard shortcuts

qt:shortcut

qt:shortcut KEYprocedure

Creates a keyboard-shortcut action for KEY, which should be a string naming a key-sequence, for example "Ctrl+E". See the Qt documentation for the interpretation of this string. qt:shortcut returns an <qt-action> instance that can be added to a widget with qt:add-action.

qt:add-action

qt:add-action WIDGET ACTIONprocedure

Adds the given action to WIDGET.

qt:remove-action

qt:remove-action WIDGET ACTIONprocedure

Removes ACTION from WIDGET.

Miscellaneous

qt:char-encoding

qt:char-encoding #!optional ENCODINGprocedure

Selects the default character encoding for strings passed to and received from Qt. ENCODING may be one of the symbols ascii, latin1 or utf8. The default is latin1. If no argument is given, then qt:char-encoding returns the current encoding.

qt:gl

qt:gl NAME PARENT INIT RESIZE PAINTprocedure

Creates and returns a QGLWidget. INIT should be zero-argument procedure called to initialize the OpenGL context. RESIZE should be a two-argument procedure called when the widget is resized and receives the new width and height. PAINT is a zero-argument procedure called when the widget should repaint itself. GL output will be automatically flushed.

qt:classname

qt:classname OBJECTprocedure

Returns the name of the Qt class of which OBJECT is an instance.

DBus

Most of the functionality of the DBus API is exposed by these bindings.

qt:dbus-connect

qt:dbus-connect BUS SERVICE OBJECT INTERFACE SIGNAL TO #!optional SLOTprocedure

Unfortunately dbus connections are handled differently in Qt from regular singal/slot connections and this has leaked over. This function works indentically to qt:connect and can connect to both Qt objects and scheme functions.

qt:session-bus

qt:session-busprocedure

Returns a handle to the session bus.

qt:system-bus

qt:system-busprocedure

Returns a handle to the system bus.

qt:dbus-list-names

qt:list-names BUSprocedure

Returns the name of a bus (eg: (qt:dbus-list-names (qt:system-bus)) returns "System bus"). The unfortunate name of this function was the choice of the DBus API not the maintainer of the bindings.

qt:dbus-send-signal

qt:dbus-send-signal BUS OBJECT INTERFACE SIGNAL #!rest ARGUMENTSprocedure

Send a signal to a bus.

qt:dbus-register-method

qt:dbus-register-method BUS PATH FUNCTION NAMEprocedure

Register a function on a bus with a name and a path, the function must be a scheme function, but it can take arguments and name must conform to the standard Qt slot naming rules.

qt:dbus-call

qt:dbus-call BUS SERVICE PATH INTERFACE METHOD #!rest ARGUMENTSprocedure

Call a method on a bus with any number of arguments.

qt:dbus-call-with-callback

qt:dbus-call-with-callback BUS SERVICE PATH INTERFACE METHOD FUNCTION SLOT #!rest ARGUMENTSprocedure

Call a method on a bus with any number of arguments and connect the output to a function on a slot. The destination must be a scheme function.

qt:dbus-register-service

qt:dbus-register-service bus serviceprocedure

Register a service on a bus.

qt:dbus-unregister-service

qt:dbus-unregister-service bus serviceprocedure
    

Unregister a service on a bus.

    

Networking

Currently their its infancy the networking bindings support only http. See the unit tests bundled in tests.scm for how to best use this functionality.

qt:make-http

qt:make-httpprocedure

Make an http object, will have to be destroyed in the end with qt:destroy-http.

qt:destroy-http

qt:destroy-httpprocedure

Destroy an http object.

qt:http-set-host

qt:http-set-host HTTP SERVER PORTprocedure

Set the host of an http connection.

qt:http-get

qt:http-get HTTP PATHprocedure

Send an HTTP GET.

qt:http-read-string

qt:http-read-string HTTPprocedure

Read back a string from the object, this is non-blocking. The best way to use this is to connect to "done(bool)" and possibly "dataReadProgress(int,int)" on the http object to be notified when the data is available.

Variant list

The basic way of exchanging data with Qt is through QtVariantList.

qt:make-variant-list

qt:make-variant-listprocedure

These will automatically be destroyed by the garbage collector when they are no longer referenced.

qt:variant-list-remove-front

qt:variant-list-remove-front VARIANTLISTprocedure

Remove and return one element from the front of a variant list.

qt:variant-list-insert-back

qt:variant-list-insert-back VARIANTLIST OBJ #!optional SIGNED?procedure

Insert one element to the back of a variant list. If SIGNED? is not provided it is assumed to be true, this only affects integers.

qt:list->variant-list

qt:list->variant-list LISTprocedure

Convert a scheme list to a variant list.

qt:variant-list->list

qt:variant-list->list VARIANTLISTprocedure

Convert a variant list to a scheme list.

qt:variant-list-length

qt:variant-list-length VARIANTLISTprocedure

Return the length of a variant list.

Example

Given the file hello.ui:

<ui version="4.0" >
<class>Form</class>
<widget class="QWidget" name="Form" >
 <property name="geometry" >
  <rect>
   <x>0</x>
   <y>0</y>
   <width>295</width>
   <height>144</height>
  </rect>
 </property>
 <property name="windowTitle" >
  <string/>
 </property>
 <widget class="QLabel" name="label" >
  <property name="geometry" >
   <rect>
    <x>40</x>
    <y>30</y>
    <width>121</width>
    <height>31</height>
   </rect>
  </property>
  <property name="font" >
   <font>
    <pointsize>15</pointsize>
    <weight>75</weight>
    <bold>true</bold>
   </font>
  </property>
  <property name="text" >
   <string>Hello, world!</string>
  </property>
  <property name="alignment" >
   <set>Qt::AlignCenter</set>
  </property>
 </widget>
 <widget class="QPushButton" name="quitButton" >
  <property name="geometry" >
   <rect>
    <x>180</x>
    <y>90</y>
    <width>75</width>
    <height>31</height>
   </rect>
  </property>
  <property name="text" >
   <string>Quit</string>
  </property>
 </widget>
</widget>
<resources/>
<connections/>
</ui>

Run this to display the Window:

(use qt utils)

(define a (qt:init))
(define w (qt:widget (read-all "hello.ui")))
(qt:connect (qt:find w "quitButton") "clicked()" a "quit()")
(qt:show w)
(qt:run)

A more interesting example can be found here: egg-browser.zip.

History

0.100.3
ported build system from the qt-light egg. This egg has been set as obsolete, see the qt-light egg for qt bindings.
1.0
revamped the qt egg
0.93
(hopefully) fixed more build problems (thanks to Mario)
0.9
fixed Linux build problems and added qt:char-encoding
0.8
I forgot what I did for 0.8
0.7
added support for Windows
0.6
qt.pro is generated by setup script to force usage of correct csc (thanks to Mario Goulart)
0.5
fixed bug in string-result handling that caused random crashes (reported by Christian Kellermann and Mario Domenench Goulart)
0.4
ported to CHICKEN 4, removed Mac OS X support
0.3
generated application bundle on Mac OS X
0.2
added file dialogs and QSound support, fixed bug by making qt:show "safe"
0.1
initial release

License

Copyright (c) 2010, Andrei Barbu
Copyright (c) 2006-2010, Felix L. Winkelmann
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
conditions are met:

  Redistributions of source code must retain the above copyright notice, this list of conditions and the following
    disclaimer. 
  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials provided with the distribution. 
  Neither the name of the author nor the names of its contributors may be used to endorse or promote
    products derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

Send bugs, suggestions and ideas to: 

andrei@0xab.com

Andrei Barbu
Purdue University

Contents »