Next: Introduction, Previous: (dir), Up: (dir) [Contents][Index]
This is the qtools Reference Manual, version 1.0.0, generated automatically by Declt version 2.4 "Will Decker" on Wed Jun 20 12:27:50 2018 GMT+0.
• Introduction: | What qtools is all about | |
• Systems: | The systems documentation | |
• Files: | The files documentation | |
• Packages: | The packages documentation | |
• Definitions: | The symbols documentation | |
• Indexes: | Concepts, functions, variables and data types |
Qtools is a collection of utilities to help development with CommonQt. There are a lot of things in there, from name mapping over garbage handling to widget class definition. Some tools are straightforward, others are quite complex. I'll try to explain everything as best I can.
There are three layers working beneath Qtools, of which you need to know about in order to understand how to use the various facilities Qtools offers.
Qt is a gigantic toolkit that mainly concerns itself with GUI creation. It is cross-platform and written in C++. While its size and large user-base means that it is very mature and usable for pretty much any kind of GUI, the fact that it's written in C++ makes things complicated. The usual way to interoperate with C++ libraries and projects is to create a C API wrapper.
And this is what Smoke does. It generates a C wrapper so that other languages can make use of Qt through C-FFI. Smoke is divided up into a bunch of modules, each being associated with a part of Qt, such as qtcore, qtgui, qtopengl, phonon, etc.
The heavy lifting and ground-work that is required to interface with Smoke (and thus with Qt) is done by CommonQt. By itself, CommonQt offers a complete framework to create Qt GUIs from Common Lisp out.
Unfortunately, working with CommonQt itself is a bit awkward. While it offers everything you need, the way you have to make use of it is sub-par. Qtools attempts to help with this by offering another layer over CommonQt to smooth everything out. However, since you might not like certain parts of the Qtools ecosystem, it should be possible for you to only use the features you like, rather than being forced to use everything. So, you can always mix and match "plain" CommonQt and Qtools extensions.
In case you already know Qt, you may skip this part and go straight to the next section. I'll briefly explain some of the core Qt concepts and how they fit together. However, you should still read the official Qt documentation for anything that's left unclear.
Since Qt is a C++ library it is heavily focused around classes and methods. At the top of the class hierarchy sits QObject. Almost all classes in Qt inherit from this. The more important one for us however is the QWidget class, which already gives you everything you need to get started. It can act as a window or be contained in other widgets. It has all the sizing mechanics and is properly hooked into the event system that allows you to catch when keys are pressed, the window is resized, and so forth.
Usually you create your new widgets by subclassing something like QWidget and then overriding methods to do what you want or simply attach other widgets to it and connect them up so that they can communicate to each other via the signal system. Classes have slots and signals. Signals are a form of method signature that describe a list of arguments and their type. Slots are the corresponding methods that perform actions when a signal reaches them. Wiring things up functions by connecting a signal and a source instance to a slot and a target instance. When then a signal is signalled onto the source instance, the target instance's slot method is called.
And that's pretty much all of the core mechanics that you need to know about. For everything else, you usually refer to the documentation page for the specific class involved and see what kind of methods or signals you can use to do what you want. Seriously, the docs are good. I use them constantly while developing.
Before getting started with explaining the details on the various parts of Qtools, I'll go through a basic project setup of a project using it.
First you will want an ASDF system to define your project. In its dependencies it should contain :qtools
and the smoke modules you require, usually just :qtcore
and :qtgui
.
(asdf:defsystem qtools-intro
...
:depends-on (:qtools :qtcore :qtgui))
If you want to just try things out on the REPL real quick, just (ql:quickload '(qtools qtcore qtgui))
should suffice.
Then of course you'll usually want a package to put all your stuff in. Instead of :use #:cl
you will most likely want to :use #:cl+qt
. This package combines the symbols of the common-lisp base package, the commonqt package, and qtools. Thus all the symbols and functions you usually need for development are already included.
(defpackage #:qtools-intro
(:use #:cl+qt)
(:export #:main))
CommonQt, and Qtools itself, require a few extensions to the standard reader syntax. For this reason you will want to change the readtable using named-readtables:in-readtable
, which cl+qt
includes. Readtable changes are on a per-file basis, so you need both an in-package
and an in-readtable
call on every file.
(in-package #:qtools-intro)
(in-readtable :qtools)
This sets up everything you need to get started writing an actual GUI. So let's do that as well. In Qt things are organised as widgets. Windows are widgets, buttons are widgets, text fields are widgets, etc. Qtools mirrors this.
(define-widget main-window (QWidget)
())
This define-widget
form is syntactically equivalent to defclass
. The only change is that the first argument in the superclass list is the Qt class to inherit from. Now we'll want to add some things to display in the widget.
(define-subwidget (main-window name) (q+:make-qlineedit main-window)
(setf (q+:placeholder-text name) "Your name please."))
(define-subwidget (main-window go) (q+:make-qpushbutton "Go!" main-window))
This adds a QLineEdit widget called name
to the main-window
and sets its placeholder text to "Your name please."
. The second form adds a button called go
with a label of "Go!"
. Simple stuff. The body of the define-subwidget
form can contain any number of statements. By default, the symbols of all the other subwidgets and slots defined prior to the define-subwidget
form are bound to their corresponding values. This is useful if you for example need to define a layout, as we will do now.
(define-subwidget (main-window layout) (q+:make-qhboxlayout main-window)
(q+:add-widget layout name)
(q+:add-widget layout go))
This sets up the displaying part of our GUI, but so far we haven't made it react to anything yet. Reacting to events in Qt happens through signals and slots. Slots are functions that receive signals, and signals are event carriers.
(define-signal (main-window name-set) (string))
(define-slot (main-window go) ()
(declare (connected go (pressed)))
(declare (connected name (return-pressed)))
(signal! main-window (name-set string) (q+:text name)))
(define-slot (main-window name-set) ((new-name string))
(declare (connected main-window (name-set string)))
(q+:qmessagebox-information main-window "Greetings" (format NIL "Good day to you, ~a!" new-name)))
We're doing things a bit roundabout here to illustrate creating signals. define-signal
introduces a new signal called name-set
that takes a single string
as argument. We then define a new slot that is connected to the go
button's pressed
signal (which has no arguments) as well as the name
field's return-pressed
. We then simply fetch the current text of our name
field and send it out again with our custom signal. The second slot catches this signal again and uses it to display a message box.
You can now try and see what kind of magical wonders you have created by using with-main-window
to launch everything: (with-main-window (window 'main-window))
. This will block until your window is closed, as Qt needs to capture the thread to handle events.
And that's that. The only thing we didn't take a look at here is define-override
, which allows you to define override functions for your Qt classes. So, if you for example want to manually draw onto a widget you can override its paintEvent
method using this.
(define-override (main-window paint-event) (event)
(declare (ignore event))
(with-finalizing ((painter (q+:make-qpainter main-window)))
(q+:fill-rect painter (q+:rect main-window) (q+:qt.white))))
This'll make the background of our window completely white. The important thing to note here is the with-finalizing
. What has been rather well hidden from you so far, is that as Qt is a C++ framework, you will have to do manual memory management. Qtools makes this a lot easier by offering macros and automations to take most of it off of your hands. For example, all the sub widgets we defined are automatically deleted once the main window is.
A general note about developing with Qtools/CommonQt: While custom function bodies such as from qt-slots, overrides, initializers, and finalizers reside on the CL side and can thus be redefined at any time and take effect immediately, adding or removing qt-slots and overrides will not affect already created instances. This is to say, if you run your application and recompile your override, the effect will be visible immediately. But if you add a new slot, override, or signal, the existing instance will not have them. This is due to the fact that these things need to be tied to the C++ class, which will not update existing instances when it is changed, like CLOS usually does. This means that if you change a running widget by adding new components, you need to recreate or restart it to see the effects.
So, you've built a neat little Qt application and you would like to deploy it and ship it to people that aren't developers. For this, you will want to dump a binary and bundle it together with the necessary shared libraries. Qtools will take care of this for you, to the point where it becomes very trivial to do.
You will need an ASDF system that compiles your program and add the following options to your system definition:
:defsystem-depends-on (:qtools)
:build-operation "qt-program-op"
:build-pathname "executable-name"
:entry-point "my-package:my-launch-function"
You can change the string of :build-pathname
to whatever pathname-name you'd like your executable to have. You should change the stirng of :entry-point
to be a designator for an external symbol that is either your main window class name, or a function that handles the launching of your GUI.
Once you have updated your ASD, you should launch a clean instance of your implementation from the command line -- make sure not to load slime or anything else that creates threads. Then simply invoke (asdf:operate :build-op :system-name :force T)
. For sbcl, that would be:
sbcl --eval "(asdf:operate :build-op :system-name :force T)"
This will compile your system, gather some info on it, copy the necessary shared libraries to the deployment folder, and finally dump an image with your system ready to go. It should put it all into a new bin
folder within your project's root. If everything went right, you should be able to just launch the executable within and be greeted with your nice GUI. You can then just ZIP up the build folder and ship that-- it should contain all of the necessary shared library dependencies to run outside of your development environment.
As an example for a working system that can be deployed, have a look at halftone or cl-gamepad-visualizer.
For more customisation and other details of the deployment system, see the underlying library Deploy.
If you need to debug the built binary on Windows, the default behaviour is a bit annoying, as it causes Windows to completely prevent all terminal output. To circumvent this, you must either run it under mintty, or deploy it with the feature :qtools-deploy-console
set before the build-op.
Common Lisp and C++ follow different naming conventions for classes, variables, methods, and types. Qtools offers a couple of functions to attempt to translate between the two. Finding a Qt class can be done with find-qt-class-name
. It searches a static table of known Qt classes (*qt-class-map*
) by first stripping all dashes from the name, and then case-insensitively finding a matching name.
Translating method names can be done through to-method-name
, which translates dashes to mean that the next character should be in uppercase. So foo-bar
is fooBar
. In case you pass it a string instead of a symbol however, it will not do any translation. This is important to take care of edge-cases, where this primitive translation would prohibit using a certain name. If you need a method signature instead of just a name, there are specified-type-method-name
that takes a name and a list of type specifiers, and determined-type-method-name
, which attempts to determine the type of the arguments, rather than requiring type specifiers directly.
Types are translated using qt-type-of
, eqt-type-of
, qt-type-for
, and to-type-name
. Where qt-type-for
translates a type specifier and qt-type-of
tries to determine the type through a value. Reversing from a Qt type specifier to a CL type is possible with cl-type-for
and ecl-type-for
.
In C++ there usually is no garbage collector, so you need to carefully clean up yourself or you'll create a memory leak. In Common Lisp we're used to the luxury of not having to worry about this, thanks to garbage collection. Sadly, we cannot use the garbage collector to also take care of C++ objects, as they live in a different world not governed by us. So, garbage collection of Qt objects is still our own worry.
To make this all just a smidgeon easier, Qtools introduces a system of finalizables, the central point of which is the finalize
generic function. This function should take care of all necessary cleanup when an object is no longer needed. For qobject
s, this means running eventual cleanup (through finalize-using-class
) and then being delete
d, thus properly removed from memory. However, finalize
can not only be used for Qt objects, but for anything else as well. Especially interesting here are finalizable
objects, whose slots can specify an additional argument :finalized
, which dictates whether finalize
is run on the slot's value when the class instance is finalize
d.
Often times we only need Qt instances for a certain lexical context of code. For this case, with-finalizing
(and with-finalizing*
) can be used, which is a counterpart to let
that calls finalize
on all its bindings once the form exits. This will take care of most cases. For cases where the instance may escape, or has to stay bound in a closure, there's with-gc-finalized
. This wraps the value of each binding in a gc-finalized
object. Using such a container, we can use Common Lisp's garbage collector to keep track of the references and, once the object is garbage collected it calls finalize
on its inner value, ensuring proper removal. The with-gc-finalized
uses a symbol-macrolet
to ensure that you don't have to worry about the boxing. However, if you manually use gc-finalized
objects, there's the make-gc-finalized
and unbox
functions (with corresponding reader macros #>
and #<
in the :qtools
read-table).
While this kind of system takes care of a lot of cases, it's still not perfect and it may happen that you accidentally create a memory leak somewhere. I wish there was an easier way, but alas, life is difficult. You can try to solve this kind of situation by debugging Qtools and keeping track of which objects get finalized and which don't.
Another occasional task is to copy an object instance. Qtools offers a copy
and copy-using-class
methods which handle proper copying for a couple of Qt objects, but sadly by far not all. If you want to use the copying system for a class that isn't handled by Qtools by default, you can define your own using define-copy-method
.
Qtools will handle the printing of QObject instances as well and provides you with a mechanism of defining print methods for a qclass, just like you normally would for CL classes by print-object
. Simply use define-print-method
.
Qt deals with widgets. As such, making everything associated with them simple and easy to use should be a primary objective. Qtools' widget system attempts to do exactly that. The central part to this is the define-widget
macro. This expands to a defclass
with the following effects: It sets widget-class
as the metaclass, sets the first item of the superclass list as the qt-superclass, and injects widget
as a superclass, if it isn't one already. This means that essentially you can use anything you could in a standard defclass
without having to worry about the necessary default options.
However, just with a single define-widget
you won't get far ahead. You still need to use CommonQt's way of declaring slots, signals, and overrides, which is quite cumbersome. You can do that of course, but there is a more convenient method, which is to use define-slot
, define-signal
, and define-override
. These essentially translate to class options, albeit in a detached way. Each of these define statements is of the following syntax:
(define-* (widget-class name) arglist &body body)
Some of them take optional extra arguments in the name-list, such as a method-name in the case of define-slot
and define-override
. In the case of define-signal
the body is discarded. However, even with these extensions things are rather cumbersome: You need to manually define slots for each of the widgets you want to use inside your widget class, and define their behaviour in an initialize-instance
function. This is unwieldy, which is why Qtools also adds define-initializer
, define-finalizer
, and define-subwidget
. The first two follow in signature to the above minus the arglist
and do what you might expect them to do: handle initialization and finalization. The initializer and finalizer forms take an optional priority argument in their name-list. The higher, the sooner. define-subwidget
on the other hand looks like this:
(define-subwidget (widget-class name) initform &body body)
And its effects are two-fold. First, it adds a finalized slot to the widget-class called name. Then, it adds an initializer (with priority 10) that sets the slot-value to the value of initform
and then evaluates the body
forms. This by itself takes care of the repetitive slot and initializer definition, but without an extra helper called with-slots-bound
, it would still be annoying to write functions, as you would have to reference widgets using slot-value
everywhere. with-slots-bound
is like with-slots
, but it binds all direct class-slot values to their respective slot names. Every define-*
function's body is automatically wrapped in a with-slots-bound
, to make this convenience possible.
If you do not like this behaviour, due to potential symbol clashes and general confusion that might arise from the implicit action, you can instead use cl+qt:defmethod
and declare
statements. This is actually what all the define-*
(with the exception of define-signal
) expand to: A cl+qt:defmethod
with an appropriate declaration inserted into the body. The cl+qt:defmethod
behaves exaclty like cl:defmethod
with the exception of allowing the handling of custom declaration forms. Qtools defines the following declarations: slot
, override
, initializer
, and finalizer
. In the case of a slot
definition, an extra declaration called connected
is also available. The effects of the declarations are as you might expect, and have the following signatures:
(slot slot-name args)
(connected slot-name (signal-name &rest args))
(override &optional method-name)
(initializer &optional (priority 0))
(finalizer &optional (priority 0))
The user may define additional declarations using define-method-declaration
.
At this point it is useful to note about the general startup sequence of a widget. Once make-instance
is called, it calls to initialize-instance
. Qtools defines a primary method on this specialized on the widget class. It then immediately calls the next method (call-next-method
), followed by construct
which should call qt:new
, instantiating the C++ parts. Following that are the initializers in the order of their priority (highest goes first). This means that if you (for some reason) define an :after
method on initialize-instance
for your own widget, it will be run after all initializers have completed. For finalization it is the same: all finalizers are run before your own finalize
method is run. However, if you define a :before
method on finalize
for your class, it will be run before the :finalized
slots are finalized, otherwise all primary and :after
methods should not access :finalized
slots anymore. If you absolutely do need to do things before normal initialization or finalization, you can define an :around
method.
One last widget-related definition form is define-menu
, which is a very convenient way of specifying menus:
(define-menu (my-widget File)
(:item ("Open..." (ctrl o))
(open-file))
(:menu recent-files)
(:separator)
(:item ("Save" (ctrl s))
(save-file))
(:item ("Save As..." (ctrl alt s))
(save-file NIL))
(:menu "Export"
(:item "PNG" (save-file NIL "png")))
(:separator)
(:item ("Quit" (ctrl q))
(#_close widget)))
Out of the box, it supports :item
, :menu
, and :separator
components. The item takes a name, which can be either a string for a label, a list of string and keyboard mnemonic, or a symbol indicating the class slot that contains the item widget, and it takes a body of forms to execute if the item is triggered. Menus take a name as a string and a body of components to contain, or a symbol indicating the slot that contains the menu widget. New components can be added with define-menu-content-type
.
If your widget has a Qt superclass to whose constructor you would like to pass certain arguments, you can do so by adding a method on construct
that calls qt:new
with the arguments you need. You can also use a shorthand to do the same by adding a (:constructor ..)
option to your widget definition form. This expands to a defmethod
form that binds all slots (with-all-slots-bound
) and otherwise just contains a call to qt:new
supplying the arguments of the option form verbatim. In effect this means that any unquoted symbol in the option denotes a slot reference. Note that the call to construct
happens before the widget initializers are run. Thus you will not be able to use slot values that are set by subwidgets or initializers.
As a final touch, Qtools offers macros for connecting slots and emitting signals. These translate to CommonQt's emit-signal
and connect
functions, and thus just offer a bit of syntactic sugar. They're called signal!
and connect!
. Their use is simple enough:
(connect! input (text-edited string) widget (text-changed string))
(signal! input (text-edited string) "Eyyyy")
An experimental variant for the adventurous is generic-signal
, which attempts to determine the argument types by their values at run-time. It does therefore not require specifying the type explicitly, but might instead screw up and choose a wrong type for the signal and thus fail to emit.
By default with CommonQt, calling Qt methods happens with the #_
reader macro. This requires you to follow the proper case of the class and method names. Having this kind of mixture of conventions in the code is a bit jarring. While Qtools offers solutions to deal with the discrepancies of defining your own classes and widgets using the various define-*
macros, Q+ fixes the method calling discrepancy. In order to use Q+ you have a choice of either using the q+
macro, or using the :qtools
read-table. Using the q+
macro directly an example translates like this:
(let ((widget (#_new QWidget)))
(#_setWindowTitle widget "Hello!")
(#_show widget)
(#_exec *qapplication*))
(let ((widget (q+ make-qwidget)))
(q+ set-window-title widget "Hello!")
(q+ show widget)
(q+ exec *qapplication*))
And the same using the readtable:
(let ((widget (q+:make-qwidget)))
(q+:set-window-title widget "Hello!")
(q+:show widget)
(q+:exec *qapplication*))
The difference is minimal in the typed code. However, the second approach will give you the convenience of letting the editor display the possible arguments and a docstring linking to the Qt methods. The second example is read by the Common Lisp reader to the first example. There is therefore no code difference in how the two work. If you use the cl+qt
package, you can also take advantage of an extended setf
macro. Using it, the second line would look like so:
(setf (q+ window-title widget) "Hello!")
Some of the setter functions require multiple values to be set at once. The updated setf
can also deal with that:
(setf (q+ window painter) (values 0 0 100 100))
The setf
has extra support for q+
, but is otherwise identical to cl:setf
and actually expands to that for all other places.
In order to access enum values, you simply use the class name followed by a dot and the enum name. Constructors are the class name prefixed with "make". Static functions are the class name, a dash, and the method name in the standard translation scheme.
(q+:qt.blue)
(q+:make-qpushbutton "Foo!")
(q+:qmessagebox-information parent "!" "hello!")
For the specific arguments, names, and everything else, refer to the Qt4.8 documentation. It's very good, trust me. The only thing you need to be aware of is the name conversion rules that Q+ uses to determine the proper Lisp symbol to use:
QImage::constScanLine
=> q+:const-scan-line
Foo::set_widget
=> q+:set_widget
QImage::InvertRgb
=> q+:qimage.invert-rgb
QImage::Format_ARGB32_Premultiplied
=> q+:qimage.format_argb32_premultiplied
QFileDialog::getExistingDirectory
=> q+:qfiledialog-get-existing-directory
QImage::QImage
=> q+:make-qimage
For Q+ to work seamlessly in conjunction with ASDF systems and compiling/loading code, you have to make sure that the smoke modules are set up correctly.
q+
and the reader extension dynamically compile wrapper functions for the Qt methods you access. You can, however, also precompile all possible methods for the currently active set of smoke modules. To do this, you can either :depends-on (:q+)
or compile a source file using write-everything-to-file
and include it in your ASDF system. If you choose this approach, you will not need to switch the readtable or use the q+
macro, as the package will be available fully populated.
In order to be able to use the various parts of Qt, the corresponding smoke modules need to be loaded. By default CommonQt loads qtcore
and qtgui
when make-qapplication
is called. However, if you want to use, say, the OpenGL parts you'll also need qtopengl
.
Qtools provides ASDF systems for all the different smoke modules. That way, you can simply push the modules you want into your project's ASDF system dependencies and it'll ensure that the modules are available at compile and load time. Having the modules loaded at both times is especially important for Q+ to work properly. An example system making use of this would look like
(asdf:defsystem foo
...
:depends-on (:qtcore :qtgui))
For a list of available smoke modules, see *smoke-modules*
.
In some cases it is vital to minimise overhead to a method call. Since usually dispatch is dynamic at run-time and un/marshalling of arguments and return values is involved, the standard way of calling methods might be too slow. In that case, you can use Qtools' fast-call mechanism to perform a method call as quickly as possible. At a cost, naturally.
(let ((size (q+:make-qsize 100 100)))
(fast-call (set-height QSize int) size 200)
size)
Fast-calling is possible if you know the exact method signature to call and are willing to translate the arguments to their proper required CFFI types. In the case of passing QObjects, you must pass their pointer. You can get that pointer by qt::qobject-pointer
.
A couple of example applications using Qtools can be found in the examples/ folder: qtools-evaluator
, qtools-titter
, qtools-melody
, and qtools-opengl
. Each of them can be loaded by their name, and launched using the main
function from their package.
In order to account for your own objects and operations you can extend the copy
and finalize
functions by using define-copy-method
and define-finalize-method
or defmethod
directly. The two define macros bring the convenience of automatically resolving to a Qt class (and thus using copy/finalize-using-class
) if possible, making it all look a bit cleaner.
(define-copy-method (instance QPixmap)
"Creates a new QPixmap using QPixmap::copy (deep copy)."
(#_copy instance (#_rect instance)))
Since copying and finalizing are operations associated with a certain amount of ambiguity, it is advisable to always write documentation strings for your copy
/finalize
methods. That way users can get a better idea of what will happen by reading about it using describe-copy-method
and describe-finalize-method
respectively.
defmethod
declarationsUsing define-method-declaration
you can add your own processing to method declarations. Your function should extract the necessary information from its declaration arguments and the *method*
form. Each method declaration processing function should return a single form (like a macro) to be put before the resulting defmethod
. The existing declaration processors are really short:
(define-method-declaration override (&optional name)
(let ((slot (qtools:to-method-name (or name (form-fiddle:lambda-name *method*)))))
(with-widget-class (widget-class)
`(set-widget-class-option ',widget-class :override '(,slot ,name)))))
In this example we're using form-fiddle to parse the method form. Using a library like that to ensure proper destructuring is important, as otherwise it's easy to accidentally butcher the method form, or get the wrong information.
The menu definition form allows for arbitrary content types, so you may add new ones yourself by using define-menu-content-type
. Each content type definition can return two values: an initform and a side-form. The initform will be put into the initialization function for the menu and thus evaluated when the widget is created. The side-form is put alongside the initializer definition and thus evaluated during compilation. If your menu type needs to modify the widget class in some way, that should be done through the side-forms. If it needs to connect signals, add items, or perform similar actions that involve Qt, that should go into the initform. You can call the expansion of other component types using build-menu-content
. During the time your content-type function is run, *widget*
is bound to the class-name of the widget and during initialization it is bound to the actual widget instance.
Qtools has grown to be a large library with a lot of rather complicated concepts. I will try to describe them here, in order to retain some information in non-code form and make things clearer to the average user. It is not necessary to read and understand this section to use Qtools, but it may be useful to be aware of the underlying ideas and functionality that make Qtools work.
A finalizable is implemented using two classes, one serving as the metaclass and the other as a superclass. The metaclass is required in order to allow a custom slot type that supports the :finalized
argument. The superclass is necessary in order to allow methods such as finalize
to operate on instances of the finalizable classes. The handling of the finalized slots is done through a general method on finalize
that scans through the slots of the class instance and then calls finalize
on each slot for which the definition is set to be :finalized
. This makes finalization of class slots automatic and convenient.
Since finalizables don't add any metaclass properties, there is no need to manually calculate inheritance order. However, as with all custom slot definitions, the slot properties must be copied over from the direct-slot instance to the effective slot. In the case of finalizable-class
this happens in compute-effective-slot-definition
.
In order to support finalizing of Qt class instances that don't have a CL class equivalent, the finalize
method is extended wit ha finalize-using-class
that is dispatched to using the Qt class and the instance of a qobject
instance is passed to finalize
.
As with finalizables, the widget is implemented using two classes, the widget-class
metaclass and the widget
superclass. These both inherit from the finalizable equivalents. The main crux of the widget-class
lies in its widget-class-direct-options
and widget-class-extern-options
. The direct options are the options that are passed to a re/
initialize-instance
(and thus also to defclass
). They're caught in the appropriately specialised methods and then stored on the class. The effect of this is that we can fully recompute the class definition at any time, and potentially add or remove options without influencing the original defclass
statement. This is where the extern-options come in.
Using set-widget-class-option
options can be added to the class definition dynamically at any point in the program. This function then adds the option to the class' extern-options and then calls reinitialize-instance
, which in turn causes the class to get effectively redefined outside of its defclass
form. This redefinition also allows us to change CommonQt class options. Using this we can create forms outside of the original defclass
that act as if they were actually options in the defclass
form.
Qtools effectively only provides two forms that do this: define-signal
and defmethod
. The define-signal
is relatively straightforward and simply expands to a class option set to add a new signal option. The defmethod
is an extensible machine in itself.
What's special about the cl+qt:defmethod
is that it inspects the declaration forms in the method body. It then checks for each declaration form whether a handler function exist and if so, calls that function. Such a method-declaration
function can then return forms to be put into the macroexpansion of the cl+qt:defmethod
, before the resulting cl:defmethod
. The processed declaration is then left out of the cl:defmethod
form as it is assumed that it isn't a standard common lisp declaration. However, the declaration function also has the ability to change the contents of the cl:defmethod
form itself, by manipulating *method*
. This allows the declaration to output special handling for the method body, for example.
This kind of extensible declaration mechanism is necessary both to allow further evolving of Qtools in the future as well as adaptation by users. It also offers a very "native-like" way of specifying external effects of a method. Qtools uses this construct then to allow definition of slots, overrides, finalizers, and initializers.
In case the user doesn't appreciate the defmethod
way, Qtools then provides define-*
alternative functions that simply wrap over defmethod
, establish some default bindings, and take care of naming and specialising the method.
The define-subwidget
deserves special attention here, as it does more work than the rest. A large part of defining widgets is adding sub-components to it, which is a task that usually involves a lot of repetition or awkward function sharing: Setting up a slot to hold the instance, defining or using an initializer to set it up. define-subwidget
makes this both distributed and simple by both taking care of setting up an appropriate initializer function, and automatically adding the slot to the class using, again, set-widget-class-option
. This slot is also always automatically set to be finalized
in order to ensure that all widgets are properly cleaned up when the GUI is no longer needed.
A minor problem regarding this approach is the same problem that appears with all of CL's definition forms. While developing incrementally, merely removing the definition form from the source file, will not actually remove it from the image. This can trip developers up, as definitions will still be active later. In this case it means having widgets still sticking around, or initializers running, etc. For this purpose there are corresponding remove-*
functions to all the define-*
functions to allow easy removal. This part cannot possibly be automated due to the nature of Common Lisp, but it is at least simple to correct should the need arise.
CommonQt's way of dealing with method calls is the simple and most direct way of doing it. The first possible alternative to remove the need for typing method names in their corresponding case would be to simply introduce a different reader macro that automatically translates a example-function
-like name into exampleFunction
as is done already in other parts of Qtools. However, this has two downsides, the first being that there does not exist a 1:1 mapping of methods anywhere. The dynamic computation of the function name means that there isn't a full correspondence table anywhere. The second downside is that methods are still not passable as first-class objects.
The way to solve this is to generate actual CL wrapper functions to the method calls. This allows us to use them as first-class objects, have at least compile-time argument number checking, and have a linkage of wrapper name to Qt method by listing it in the docstring.
In order to achieve this, there are two possible choices. First, the entirety of all possible wrappers can be computed once, and then subsequently loaded into the image and used directly. However, this creates two new problems. Computing all wrappers, compiling them, and loading them, takes a long time and subsequently litters the image with thousands of functions and symbols that won't ever be used in the program. Then, we have a problem with the smoke modules, as we need to know which modules will be used in a potential application ahead of time, load them all, and then generate the wrappers. We cannot generate wrappers for each module separately, as the methods from different classes share the same wrapper functions. This means that whenever a different set of modules is needed, the wrappers need to be regenerated, recompiled, and reloaded. A lot of time and space goes to waste with this. However, this approach also has an advantage: As all functions are always available, it is easy to develop with. Arguments and docstrings will be readily available through the editor. Qtools offers this approach through q+-compile-and-load
.
The second approach is to dynamically only compile what is needed. That way, the image only ever contains wrappers for function that are actually called (at some point). However, this complicates things a lot. When a function is compiled that calls such a function, it doesn't exist yet. Even worse, when the form is read, the symbol for the function does not exist yet and isn't external! In order to catch this problem, a modified reader macro is necessary. This reader macro will detect when a call to a wrapper function is made, and instead transform it into a macro call that then sees to it that the wrapper will be created. Modifying the reader in such a way is a heavy change, and should only be used sparingly, however there is no alternative here. Qtools does not force you to use this reader extension, you can always just use the macro directly.
However, dynamic compilation complications don't end there. Since we never dump the function to a file, it only ever exists in the environment it was compiled in. That means, if you compile a function that then dynamically generates the wrapper function, the wrapper won't be available anymore at load time. Qtools solves this issue with a trick. The q+
macro expands to a load-time-value
form that then generates the wrapper function. That way, the wrapper will always be available at load- and execution time, while posing no overhead to the execution time, as it will return a value to that won't impact anything.
Function referencing gets the same problems as function calling, so the Qtools readtable also contains an overridden #'
reader macro to handle that. In the case of a wrapper call, it expands to Q+FUN
which in turn expands to a load-time-value
form that generates and returns the function object.
As is probably obvious by now, Qtools also implements the second approach. Therefore, the choice as a user is yours: You can statically precompile everything and use it directly, or you an use the dynamic on the fly compilation using either a readtable expansion, or a simple macro. The concepts to make this all possible are rather complex, but the actual function wrapper compilations are quite straight-forward. The system is currently not suited for extension, but I see no need to allow that as the kind of Qt methods that can exist are fixed and Q+ should handle all that are relevant.
Q+ does one last thing to fix the "issue" of having setters instead of being able to use setf
. For this purpose it has an extended setf
macro that checks if a place is a function in the Q+ package. if so, this place/value pair is instead expanded to a call to the appropriate wrapper function with the function name transformed. However, that's not the only reason to do this. The second is that some setters require multiple arguments to be set at once. Usually, cl:setf
allows for cases like these by permitting setf expanders to accept multiple values. However, the number of values is fixed, and there's no way to dynamically know how many values where passed. Since Q+ needs to dispatch based on the number of values, this is not a viable approach. Therefore, with cl+qt:setf
a (values ..)
value form is specially treated and its arguments are inlined into the wrapper call. This also means that it isn't possible to use multiple values of a returning function as the values to a setter call, however while that is an inconsistency, I don't think it will be a big issue. If it turns out to be problematic in the later run, this will have to be changed to a dynamic analysis at run-time, which is an overhead I wanted to avoid.
Currently the following implementations are tested and supported by Qtools:
You can run it on x86_64 Linux, OS X, and Windows, where SBCL on Linux is the recommended platform.
It may or may not work more or less smoothly on other implementations and platforms depending on MOP and CommonQt support and general implementation quirks.
Next: Files, Previous: Introduction, Up: Top [Contents][Index]
The main system appears first, followed by any subsystem dependency.
• The qtools system: |
Nicolas Hafner <shinmera@tymoon.eu>
Nicolas Hafner <shinmera@tymoon.eu>
Artistic
A collection of tools to aid in development with CommonQt.
1.0.0
qtools.asd (file)
Files are sorted by type and then listed depth-first from the systems components trees.
• Lisp files: |
Next: The qtools/package<dot>lisp file, Previous: Lisp files, Up: Lisp files [Contents][Index]
qtools.asd
qtools (system)
Next: The qtools/toolkit<dot>lisp file, Previous: The qtools<dot>asd file, Up: Lisp files [Contents][Index]
Next: The qtools/class-map<dot>lisp file, Previous: The qtools/package<dot>lisp file, Up: Lisp files [Contents][Index]
package.lisp (file)
qtools (system)
toolkit.lisp
Next: The qtools/name-translation<dot>lisp file, Previous: The qtools/toolkit<dot>lisp file, Up: Lisp files [Contents][Index]
toolkit.lisp (file)
qtools (system)
class-map.lisp
repopulate-class-map (function)
Next: The qtools/dispatch<dot>lisp file, Previous: The qtools/class-map<dot>lisp file, Up: Lisp files [Contents][Index]
class-map.lisp (file)
qtools (system)
name-translation.lisp
Next: The qtools/finalizable<dot>lisp file, Previous: The qtools/name-translation<dot>lisp file, Up: Lisp files [Contents][Index]
name-translation.lisp (file)
qtools (system)
dispatch.lisp
Next: The qtools/gc-finalized<dot>lisp file, Previous: The qtools/dispatch<dot>lisp file, Up: Lisp files [Contents][Index]
dispatch.lisp (file)
qtools (system)
finalizable.lisp
Next: The qtools/copying<dot>lisp file, Previous: The qtools/finalizable<dot>lisp file, Up: Lisp files [Contents][Index]
finalizable.lisp (file)
qtools (system)
gc-finalized.lisp
Next: The qtools/printing<dot>lisp file, Previous: The qtools/gc-finalized<dot>lisp file, Up: Lisp files [Contents][Index]
gc-finalized.lisp (file)
qtools (system)
copying.lisp
Next: The qtools/signal<dot>lisp file, Previous: The qtools/copying<dot>lisp file, Up: Lisp files [Contents][Index]
copying.lisp (file)
qtools (system)
printing.lisp
Next: The qtools/widget<dot>lisp file, Previous: The qtools/printing<dot>lisp file, Up: Lisp files [Contents][Index]
printing.lisp (file)
qtools (system)
signal.lisp
Next: The qtools/widget-defmethod<dot>lisp file, Previous: The qtools/signal<dot>lisp file, Up: Lisp files [Contents][Index]
signal.lisp (file)
qtools (system)
widget.lisp
Next: The qtools/widget-convenience<dot>lisp file, Previous: The qtools/widget<dot>lisp file, Up: Lisp files [Contents][Index]
widget.lisp (file)
qtools (system)
widget-defmethod.lisp
Next: The qtools/widget-menu<dot>lisp file, Previous: The qtools/widget-defmethod<dot>lisp file, Up: Lisp files [Contents][Index]
widget-defmethod.lisp (file)
qtools (system)
widget-convenience.lisp
Next: The qtools/readtable<dot>lisp file, Previous: The qtools/widget-convenience<dot>lisp file, Up: Lisp files [Contents][Index]
widget-convenience.lisp (file)
qtools (system)
widget-menu.lisp
Next: The qtools/generate<dot>lisp file, Previous: The qtools/widget-menu<dot>lisp file, Up: Lisp files [Contents][Index]
widget-menu.lisp (file)
qtools (system)
readtable.lisp
make-reader-for-function (function)
Next: The qtools/dynamic<dot>lisp file, Previous: The qtools/readtable<dot>lisp file, Up: Lisp files [Contents][Index]
readtable.lisp (file)
qtools (system)
generate.lisp
Next: The qtools/precompile<dot>lisp file, Previous: The qtools/generate<dot>lisp file, Up: Lisp files [Contents][Index]
generate.lisp (file)
qtools (system)
dynamic.lisp
Next: The qtools/deploy<dot>lisp file, Previous: The qtools/dynamic<dot>lisp file, Up: Lisp files [Contents][Index]
dynamic.lisp (file)
qtools (system)
precompile.lisp
write-forms (function)
Next: The qtools/fast-call<dot>lisp file, Previous: The qtools/precompile<dot>lisp file, Up: Lisp files [Contents][Index]
precompile.lisp (file)
qtools (system)
deploy.lisp
qtools-library-p (function)
Next: The qtools/documentation<dot>lisp file, Previous: The qtools/deploy<dot>lisp file, Up: Lisp files [Contents][Index]
deploy.lisp (file)
qtools (system)
fast-call.lisp
Previous: The qtools/fast-call<dot>lisp file, Up: Lisp files [Contents][Index]
fast-call.lisp (file)
qtools (system)
documentation.lisp
Next: Definitions, Previous: Files, Up: Top [Contents][Index]
Packages are listed by definition order.
• The cl+qt package: | ||
• The qtools package: |
Next: The qtools package, Previous: Packages, Up: Packages [Contents][Index]
package.lisp (file)
org.shirakumo.qtools+common-lisp
Previous: The cl+qt package, Up: Packages [Contents][Index]
package.lisp (file)
org.shirakumo.qtools
Definitions are sorted by export status, category, package, and then by lexicographic order.
• Exported definitions: | ||
• Internal definitions: |
Next: Internal definitions, Previous: Definitions, Up: Definitions [Contents][Index]
• Exported special variables: | ||
• Exported macros: | ||
• Exported compiler macros: | ||
• Exported functions: | ||
• Exported generic functions: | ||
• Exported conditions: | ||
• Exported classes: | ||
• Exported types: |
Next: Exported macros, Previous: Exported definitions, Up: Exported definitions [Contents][Index]
A list of functions to invoke (in sequence) during the warm-boot.
Use this to run customised startup, prepare, or load functions.
deploy.lisp (file)
A list of functions to invoke (in sequence) during the build.
Use this to run customised cleanup, compile, or deployment functions.
deploy.lisp (file)
Variable containing the path to the directory that is being deployed to.
This is bound when *BOOT-HOOKS* functions are called.
deploy.lisp (file)
A list of loaded smoke modules when PROCESS-ALL-METHODS is called. This is useful to keep track over environments which modules are actually available for compilation.
generate.lisp (file)
Contains the whole DEFMETHOD form that is currently being processed. If you modify the contents of this variable, the changes will be reflected in the outputted method definition form. However, no declaration that is processed by method-declarations will ever appear in the output.
widget-defmethod.lisp (file)
A hash-table of C++ operators to CL function names.
generate.lisp (file)
Table mapping a *TARGET-PACKAGE* symbol to a list of
associated Qt methods. This table should only be changed
by PROCESS-METHOD. If you modify yourself without knowing
exactly what you’re doing you’ll most likely run into problems.
Methods/functions contained in this table are available
for compilation.
See QTOOLS:PROCESS-METHOD
See QTOOLS:COMPILE-WRAPPER
generate.lisp (file)
An EQUALP hash-table of all Qt4.8 class names to themselves as strings.
class-map.lisp (file)
A vector of all Qt4.8 class names as strings.
class-map.lisp (file)
A list of functions to invoke (in sequence) when the program quits.
Use this to run customised saving or cleanup functions.
deploy.lisp (file)
A list of all possible smoke modules.
These modules provide the C wrappers required to work with the respective Qt parts. Usually you will only need QTCORE and QTGUI, but for example if you need OpenGL support you’ll want QTOPENGL, or if you need phonon, you’ll want the PHONON module.
generate.lisp (file)
A list of smoke modules that need to be reloaded on boot.
The system sets this variable itself during the build.
deploy.lisp (file)
The package used to store Qt wrapper functions that the Q+ system uses. By default this package is called "Q+". The package should not contain any systems except for those generated by Qtools.
generate.lisp (file)
Bound to the class-name of the widget during component expansion and bound to the class instance during initialization.
widget-menu.lisp (file)
Next: Exported compiler macros, Previous: Exported special variables, Up: Exported definitions [Contents][Index]
Macro for a more lisp-y writing of CONNECT.
ORIGIN-FUNCTION and TARGET-FUNCTION should both be a list of the METHOD-NAME
followed by Qt argument types. The effective method name is computed as per
SPECIFIED-TYPE-METHOD-NAME.
ORIGIN and TARGET can both be either a single object or a list of objects to connect with each other.
signal.lisp (file)
Defines a new generic function.
Identical to CL:DEFGENERIC, but takes care of translating function-names with SETF to use CL:SETF instead of CL+QT:SETF.
See CL:DEFGENERIC.
dynamic.lisp (file)
Defines a translator for a one to one mapping.
The match is compared to the inputted name by STRING-EQUAL by default. A different
comparison function can be specified through the TEST keyword argument. This function
receives the given name to be translated as the first argument and the match as the
second.
The match is used as the name after being interned.
See DEFINE-SIMPLE-TRANSLATOR
name-translation.lisp (file)
Defines a method to copy an object of CLASS.
CLASS can be either a common-lisp class type or a Qt class name.
Qt class names will take precedence, meaning that if CLASS resolves
to a name using FIND-QT-CLASS-NAME a QCLASS-COPY method
is defined on the respective qt-class. Otherwise a COPY method
is defined with the CLASS directly as specializer for the instance.
In cases where you need to define a method on a same-named CL class,
directly use DEFMETHOD on COPY-QOBJECT.
See COPY-QOBJECT
copying.lisp (file)
Shorthand around DEFCLASS to create a finalizable class.
Automatically adds FINALIZABLE as direct-superclass and FINALIZABLE-CLASS as metaclass.
finalizable.lisp (file)
Defines a method to finalize an object of CLASS.
CLASS can be either a common-lisp class type or a Qt class name.
Qt class names will take precedence, meaning that if CLASS resolves
to a name using FIND-QT-CLASS-NAME a FINALIZE-QCLASS method
is defined on the respective qt-class. Otherwise a FINALIZE method
is defined with the CLASS directly as specializer for the instance.
In cases where you need to define a method on a same-named CL class,
directly use DEFMETHOD on FINALIZE.
See FINALIZE
finalizable.lisp (file)
Defines a new finalizer of METHOD-NAME on WIDGET-CLASS.
Finalizers are functions that are run immediately after the widget has been
FINALIZED, but before the main FINALIZE method kicks in. This means that the
widget will still be allocated at the time. Finalizers are executed in order
of highest PRIORITY first.
This is translated to a method definition specialised (and bound) on WIDGET-CLASS with a FINALIZER declaration. The BODY is wrapped in a WITH-SLOTS-BOUND form.
See CL+QT:DEFMETHOD
See QTOOLS:WITH-SLOTS-BOUND
See QTOOLS:FINALIZE
widget-convenience.lisp (file)
Defines a new initializer of METHOD-NAME on WIDGET-CLASS.
Initializers are functions that are run immediately after the widget has been
allocated by QT:NEW, but before any INITIALIZE-INSTANCE:AFTER methods are
executed. They are executed in order of highest PRIORITY first.
This is translated to a method definition specialised (and bound) on WIDGET-CLASS with a INITIALIZER declaration. The BODY is wrapped in a WITH-SLOTS-BOUND form.
See CL+QT:DEFMETHOD
See QTOOLS:WITH-SLOTS-BOUND
widget-convenience.lisp (file)
Defines a menu on WIDGET-CLASS with NAME and CONTENTS.
By default the following content types are available:
A :MENU form is followed by a menu text string and a
body of content forms.
A :SEPARATOR simply adds a separator at its point to
the parent and takes no further arguments.
An :ITEM form is followed by an identifier, which may
be a symbol, string, or list. In the case of a symbol,
the item is taken from the according slot on the widget.
In the case of a string the string serves as the text
for the item. For a list, the first serves as the text
and the second as an input acceptable to MAKE-CHORD.
The body of the item form can be arbitrary lisp forms
to be executed when the item is triggered.
See QTOOLS:MAKE-CHORD.
widget-menu.lisp (file)
Defines a new menu content type processor NAME.
See (SETF QTOOLS:MENU-CONTENT-TYPE).
widget-menu.lisp (file)
Define a new method declaration function of NAME.
See (SETF QTOOLS:METHOD-DECLARATION).
widget-defmethod.lisp (file)
Alias for DEFINE-WIDGET.
This is merely here for clarity.
See QTOOLS:DEFINE-WIDGET
widget.lisp (file)
Define a new OVERRIDE on WIDGET-CLASS with ARGS.
This is translated to a method definition with METHOD-NAME that specialises
(and binds) on WIDGET-CLASS, with ARGS appended to the list, and an OVERRIDE
declaration in the body. Additionally, the body is wrapped in a WITH-SLOTS-BOUND
to allow for convenient slot access.
See CL+QT:DEFMETHOD
See QTOOLS:WITH-SLOTS-BOUND
See CommonQt/override
widget-convenience.lisp (file)
Defines a method to print an object of CLASS.
CLASS can be either a common-lisp class type or a Qt class name.
Qt class names will take precedence, meaning that if CLASS resolves
to a name using FIND-QT-CLASS-NAME a QCLASS-PRINT method
is defined on the respective qt-class. Otherwise a PRINT-OBJECT method
is defined with the CLASS directly as specializer for the instance.
In cases where you need to define a method on a same-named CL class,
directly use DEFMETHOD on PRINT-OBJECT.
See PRINT-OBJECT
printing.lisp (file)
Defines a sort of generic function that dispatches by qclass.
This can be used to write methods that dispatch as CLOS would, but on Qt internal classes. In specific, it defines the following things all in one:
1. A variable *QCLASS-basename-FUNCTIONS* that contains all the methods you
define on the function.
2. An accessor function QCLASS-basename-FUNCTION that takes a qclass and
accesses the appropriate method function.
3. A function REMOVE-QCLASS-basename-FUNCTION to remove a method function.
4. A macro DEFINE-QCLASS-basename-FUNCTION to define a method on the
qclass generic function. The macro will expect a qclass, a lambda-list,
and a body as arguments.
5. A function DISPATCHER that is used as the "generic function".
Note that multiple-dispatch is not possible with this. Dispatch only ever
happens on the first argument, which must be a qclass instance. There is
also no method combination. Defining a second method on the same qclass will
simply replace the old definition.
However the local CALL-NEXT-METHOD and NEXT-METHOD-P functions are available
in a method body.
See GENERATE-QCLASS-DISPATCH-LAMBDA
See DISPATCH-BY-QCLASS
dispatch.lisp (file)
Define a new SIGNAL on WIDGET-CLASS with ARGS.
This evaluates to a simple SET-WIDGET-CLASS-OPTION that adds a new :SIGNAL
definition to the WIDGET-CLASS. The signal signature is generated using
SPECIFIED-TYPE-METHOD-NAME.
See CommonQt/signals
widget-convenience.lisp (file)
Shorthand to define wrapper methods for the given signal.
NAME ::= signal | (signal method-name)
ARGS ::= ARG*
ARG ::= qt-type | (qt-type*)
A methods with name NAME are generated that takes arguments the object to signal and the specified arguments with their according types. You may either specify a single type on each argument, or lists of correlating types for each argument. Each type is resolved as per ECL-TYPE-FOR to a type to use in the method specializers. The signal method to call is computed as per SPECIFIED-TYPE-METHOD-NAME.
signal.lisp (file)
Define a translator function for a singular type.
In addition to defining a standard translator, this constructs a name out of the given
type as well as its name. This makes it possible to use the same name in the definition
for multiple types of translators.
See DEFINE-TRANSLATOR
name-translation.lisp (file)
Define a new SLOT on WIDGET-CLASS with ARGS.
ARGS is a list of arguments, where each item is a list of two values,
the first being the symbol used to bind the value within the function
body, and the second being a type specifier usable for the slot definition
and, if possible, as a specializer in the method. You may specify an
explicit type to use for the method specializer as a third item. If no
explicit type is passed, the Qt type is translated using CL-TYPE-FOR.
In effect this translates to a method definition with METHOD-NAME that
specialises (and binds) on WIDGET-CLASS, with additional required arguments
ARGS, and a SLOT declaration. Additionally, the body is wrapped in a
WITH-SLOTS-BOUND to allow for convenient slot access.
See QTOOLS:CL-TYPE-FOR
See CL+QT:DEFMETHOD
See QTOOLS:WITH-SLOTS-BOUND
See CommonQt/slots
widget-convenience.lisp (file)
Alias for DEFINE-SUBWIDGET
This is merely here for clarity.
See QTOOLS:DEFINE-SUBOBJECT
widget-convenience.lisp (file)
Defines a new sub-widget of NAME on WIDGET-CLASS.
What this means is that a finalized slot of NAME is added to WIDGET-CLASS as well as an initializer function for the slot. The slot for the sub-widget is set to the value returned by the INITFORM, after which BODY is run. BODY is wrapped in a WITH-SLOTS-BOUND form, so all slots are conveniently available.
See QTOOLS:DEFINE-INITIALIZER
widget-convenience.lisp (file)
Define a translator function.
A translator takes a name and should translate it to the requested type of name if it can.
If it cannot, then it should simply return NIL, otherwise the translated name.
See TRANSLATOR
name-translation.lisp (file)
Shorthand over DEFCLASS.
Adds WIDGET as direct-superclass if it does not appear as a
superclass to the specified direct-superclasses. Sets
WIDGET-CLASS as metaclass and qt-class as the qt-superclass
after resolving it through FIND-QT-CLASS-NAME.
All options are fused as per FUSE-ALISTS. You may therefore use the same form multiple times.
widget.lisp (file)
Defines a new method.
This is identical to CL:DEFMETHOD with one exception:
The only difference is that declarations are scanned and
potentially specially processed. If a declaration is
recognised through METHOD-DECLARATION, it is taken out of
the method definition. The declaration processor function
then may or may not cause side-effects or spit out
additional forms to be output alongside the CL:DEFMETHOD
form.
See CL:DEFMETHOD.
See QTOOLS:METHOD-DECLARATION.
widget-defmethod.lisp (file)
dynamic.lisp (file)
Macro for a more lisp-y writing of DISCONNECT.
ORIGIN-FUNCTION and TARGET-FUNCTION should both be a list of the METHOD-NAME
followed by Qt argument types. The effective method name is computed as per
SPECIFIED-TYPE-METHOD-NAME.
ORIGIN and TARGET can both be either a single object or a list of objects to connect with each other.
signal.lisp (file)
Iterate over all WIDGETs on LAYOUT.
toolkit.lisp (file)
Performs a fast call on a given method.
This is useful if performance really matters and you have to minimise FFI
call overhead. In exchange it is required that you specify the exact method
signature you want to call and provide all arguments prepared in their proper
types as no marshalling will be done. FAST-CALL also will not read out the
return value.
METHOD-DESCRIPTOR ::= (name class-name arg-type*)
object — The instance of the class to call a method on.
Must match the given class-name.
args — The arguments to call the method with. Their types
must match the ones given in the arg-types and must
be prepared. Especially objects must be translated
to pointers manually. See QT::QOBJECT-POINTER.
name — The Q+ name of the method being called.
class-name — The Qt class name of the class the method belongs to.
At compile time a matching method number is searched for using
FIND-FASTCALL-METHOD. If no method can be found that matches the class,
name, and argument types, an error is signalled.
The fast call procedure creates a stack for the arguments by WITH-CALL-STACK.
It then uses FAST-DIRECT-CALL on the found method number, class, and
stack to perform the actual call to the method.
See FIND-FASTCALL-METHOD
See FAST-DIRECT-CALL
See WITH-CALL-STACK
fast-call.lisp (file)
Directly calls the given Qt class method on the given object using the
specified STACK as arguments to supply to the method.
Note that METHOD must be an existing Qt method number, OBJECT must be a
pointer to a class instance that is compatible with the method, and STACK
must be a pointer to an argument stack, preferably created through
WITH-CALL-STACK.
See WITH-CALL-STACK
See FAST-CALL
fast-call.lisp (file)
Finalizing SETF. The same as CL+QT:SETF, but performs a FINALIZE on the place first. The finalize is performed before the place is set, but after the new value is evaluated.
dynamic.lisp (file)
Defines a new function.
Identical to CL:DEFUN, but takes care of translating function-names
with SETF to use CL:SETF instead of CL+QT:SETF.
See CL:DEFUN.
dynamic.lisp (file)
Emits a function call to the Q+ FUNCTION with ARGS.
This macro does a bit of a complicated thing:
Firstly, it calls ENSURE-Q+-METHOD on FUNCTION to
make sure that the function object exists at compile
time. Then it emits a PROGN form that contains two
forms, the first of which is a LOAD-TIME-VALUE form
with a call to ENSURE-Q+-METHOD again. This is required
since the function compiled by ENSURE-Q+-METHOD is not
dumped to file anywhere and thus must be recreated at
load time to be available. The second form in the PROGN
is the actual function call, using the proper symbol
from the *TARGET-PACKAGE*.
See QTOOLS:ENSURE-Q+-METHOD
dynamic.lisp (file)
Emits a form that evaluates to the function object of FUNCTION.
Specifically, it returns a LOAD-TIME-VALUE form that evaluates to
the function object, while ensuring that the function does indeed
exist.
See QTOOLS:ENSURE-Q+-METHOD
dynamic.lisp (file)
Similar to QTYPECASE, but only supports equality comparisons with classes, not subtype relations. You should use this if you care about reasonably performant class type comparisons.
toolkit.lisp (file)
Similar to CASE:
KEYFORM — A form that evaluates to the key to compare against.
CASES ::= CASE*
CASE ::= (KEY form*)
KEY ::= (OR form*) | FORM | t | otherwise
toolkit.lisp (file)
Analogous to CL:TYPECASE, but for Qt classes.
See QINSTANCEP
toolkit.lisp (file)
A wrapper around CL:SETF that specially handles calls to Q+ functions.
If a place is a Q+ form, or a form calling a symbol from *TARGET-PACKAGE*,
it is translated to a proper setter call using PROCESS-Q+-SETTER. Any other
place and value pair is translated to a normal CL:SETF call.
The order of places and values is preserved.
See QTOOLS:Q+
See QTOOLS:PROCESS-Q+-SETTER
See QTOOLS:*TARGET-PACKAGE*
dynamic.lisp (file)
Macro for a more lisp-y writing of EMIT-SIGNAL.
Function should be a list of the METHOD-NAME followed by Qt argument types.
The effective method name is computed as per SPECIFIED-TYPE-METHOD-NAME.
OBJECT can be either a single object to signal to, or a list of objects.
signal.lisp (file)
Turns into a WITH-SLOTS with all slots of CLASS. Class is resolved as per ENSURE-CLASS.
toolkit.lisp (file)
Binds a populated stack area to be used in a fast-call.
ARGS ::= ARG*
ARG ::= (value stack-item-type)
value — The value to be used at the stack position.
stack-item-type — It must be a symbol from the CommonQt StackItem union.
The stack is populated in the order of the arguments. The values must be
already of their proper types to be used for SETF CFFI:FOREIGN-SLOT-VALUE.
You may use TRANSLATE-NAME STACK-ITEM to translate a common type name to
the appropriate CommonQt StackItem union value.
See FAST-DIRECT-CALL
See FAST-CALL
fast-call.lisp (file)
Executes the body as by LET and calls FINALIZE on all the objects introduced by the bindings on completion of the body. If an error occurs during the binding phase, all objects bound up until that point are still finalized. Finalizing happens in reverse order of the bindings specified.
finalizable.lisp (file)
Executes the body as by LET* and calls FINALIZE on all the objects introduced by the bindings on completion of the body. If an error occurs during the binding phase, all objects bound up until that point are still finalized. Finalizing happens in reverse order of the bindings specified.
finalizable.lisp (file)
Creates bindings as per LET with the special note that each value of a binding is wrapped
in a GC-FINALIZED. Each bound symbol is shadowed by a SYMBOL-MACROLET, which evaluates to
the bound value as per UNBOX.
In other words, this will look like a standard LET to you, but each value of the let is automatically ensured to be GC-ed and FINALIZEd once the body exits.
gc-finalized.lisp (file)
This is the main macro to start your application with.
It does the following:
1. Call ENSURE-QAPPLICATION with the provided NAME and QAPPLICATION-ARGS
2. Run the following in the main thread through TMT:WITH-BODY-IN-MAIN-THREAD
if MAIN-THREAD is non-NIL and make it non-blocking if BLOCKING is NIL.
3. Establish a handler for ERROR that calls the ON-ERROR function if hit.
4. Bind WINDOW to the result of INSTANTIATOR, passed through ENSURE-QOBJECT
(This means you can also just use the main window class’ name)
5. Evaluate BODY
6. Call Q+:SHOW on WINDOW if SHOW is non-NIL
7. Call Q+:EXEC on *QAPPLICATION*
This will enter the Qt application’s main loop that won’t exit until your
application terminates.
8. Upon termination, call FINALIZE on WINDOW.
toolkit.lisp (file)
Turns into a WITH-SLOTS with all direct-slots of CLASS. Class is resolved as per ENSURE-CLASS.
toolkit.lisp (file)
Binds VARIABLE to the current symbol name of the widget class as used as a specializer in the method arguments list. This also signals errors if there is no such specializer or if it is invalid.
widget-defmethod.lisp (file)
Next: Exported functions, Previous: Exported macros, Up: Exported definitions [Contents][Index]
signal.lisp (file)
Next: Exported generic functions, Previous: Exported compiler macros, Up: Exported definitions [Contents][Index]
Calls the appropriate function to parse menu content of TYPE.
See (SETF QTOOLS:MENU-CONTENT-TYPE).
widget-menu.lisp (file)
Calls all the finalizers specified on CLASS in their proper sequence.
CLASS can be either an instance of a WIDGET-CLASS, a
WIDGET-CLASS itself, or a symbol naming the class.
widget.lisp (file)
Calls all the initializers specified on CLASS in their proper sequence.
CLASS can be either an instance of a WIDGET-CLASS, a
WIDGET-CLASS itself, or a symbol naming the class.
widget.lisp (file)
toolkit.lisp (file)
Attempts to determine the CL type for the given Qt type descriptor.
Look at the source to see the mappings.
name-translation.lisp (file)
Clears the *QMETHODS* table.
See QTOOLS:*QMETHODS*
generate.lisp (file)
Compiles the wrapper function for METHOD.
This does not actually call CL:COMPILE, or change
the global environment in any way. It instead returns
a form that you can then truly compile, print, or write
to file, or whatever your intention is.
See QTOOLS:ENSURE-METHODS
See QT:QMETHOD-ENUM-P
See QTOOLS:COMPILE-CONSTANT
See QT:QMETHOD-CTOR-P
See QT:QMETHOD-COPYCTOR-P
See QTOOLS:COMPILE-CONSTRUCTOR
See QTOOLS:QMETHOD-OPERATOR-P
See QTOOLS:COMPILE-OPERATOR
See QT:QMETHOD-STATIC-P
See QTOOLS:COMPILE-STATIC-METHOD
See QTOOLS:COMPILE-METHOD
generate.lisp (file)
copying.lisp (file)
Attempts to find and return a default name to use for the application.
toolkit.lisp (file)
Prints information about the copy method for the specified class if possible.
copying.lisp (file)
Prints information about the finalize method for the given class if possible.
finalizable.lisp (file)
Prints information about the print method for the specified class if possible.
printing.lisp (file)
Returns a method designator for the FUNCTION and ARGS.
The FUNCTION is transformed as by TO-METHOD-NAME.
Argument types are determined as follows:
If the argument is a CONS, the CAR is taken as a value (and thus discarded)
and the CDR is the literal type to take. Otherwise the type is determined
by EQT-TYPE-OF.
name-translation.lisp (file)
Returns T if MAYBE-SUPERCLASS is a direct superclass of QCLASS.
dispatch.lisp (file)
Dispatches on the given-method locator by the object.
The METHOD-LOCATOR should be a function of a single argument– a qclass,
which returns the appropriate method for that class or NIL if none.
If the method-locator does not return a function for all classes in the
precedence list for the object, NO-APPLICABLE-METHOD is called.
This binds *QCLASS-PRECEDENCE-LIST*.
See QCLASS-PRECEDENCE-LIST
dispatch.lisp (file)
Same as CL-TYPE-FOR, but signals an error if no matching type could be found.
name-translation.lisp (file)
toolkit.lisp (file)
Ensures to return a CLASS. SYMBOL -> FIND-CLASS CLASS -> IDENTITY STANDARD-OBJECT -> CLASS-OF
toolkit.lisp (file)
Ensures that all methods have been generated for the currently loaded smoke modules.
See QTOOLS:LOADED-SMOKE-MODULES
See QTOOLS:*GENERATED-MODULES*
See QTOOLS:PROCESS-ALL-METHODS
generate.lisp (file)
Ensures that the Q+ FUNCTION exists by compiling it on the fly. Raises an error if no appropriate function can be found. Returns the proper *TARGET-PACKAGE* symbol for the function.
See QTOOLS:ENSURE-METHODS-PROCESSED
See QTOOLS:COMPILE-WRAPPER
See QTOOLS:*TARGET-PACKAGE*
dynamic.lisp (file)
Ensures that the QT:*QAPPLICATION* is available, potentially using NAME and ARGS to initialize it.
See QT:*QAPPLICATION*
See QT:ENSURE-SMOKE
toolkit.lisp (file)
toolkit.lisp (file)
Makes sure that THING is a usable qobject.
THING can be of type:
FUNCTION — ENSURE-QOBJECT is called on the return value of the function.
QT:QOBJECT — THING is returned.
WIDGET — THING is returned.
SYMBOL — MAKE-INSTANCE is called on THING.
STRING — QT:INTERPRET-NEW is called on THING.
toolkit.lisp (file)
Returns a list of all possible method descriptors with NAME and ARGS.
Args may be either a list of direct types to use or a list of alternative types.
In the case of lists, the argument alternatives are taken in parallel.
Examples:
(.. foo ’(a b)) => ("foo(a,b)")
(.. foo ’((a b))) => ("foo(a)" "foo(b)")
(.. foo ’((a b) (0 1))) => ("foo(a,0)" "foo(b,1)")
toolkit.lisp (file)
Returns the string designating an equivalent Qt class, if possible.
If the designator is a string, it is returned immediately without further check.
If it is a symbol, it is resolved through FIND-QT-CLASS-NAME, and if no name can
be found through that, an error is signalled.
class-map.lisp (file)
Same as QT-TYPE-OF, but signals an error if no matching type could be found.
name-translation.lisp (file)
Accesses the current global function definition named by NAME.
Identical to CL:FDEFINITION, but takes care of translating function-names
with SETF to use CL:SETF instead of CL+QT:SETF.
See CL:FDEFINITION.
dynamic.lisp (file)
(setf fdefinition) (function)
dynamic.lisp (file)
fdefinition (function)
finalizable.lisp (file)
Find the first child that is an instance of CHILD-CLASS
See FIND-CHILDREN
toolkit.lisp (file)
Find all children that are an instance of CHILD-CLASS
If FIRST-ONLY is non-NIL, only the first match is found, otherwise
a list is returned.
See QINSTANCEP
toolkit.lisp (file)
Attempts to find a matching method on the class.
This is done by iterating over all methods that match the name and comparing
the belonging class and its argument types. If you specify an argument type
that is unknown, an error will be signalled. If no matching method can be
found, NIL is returned.
See FAST-CALL
See ENSURE-Q+-METHOD
fast-call.lisp (file)
Returns the string designating an equivalent Qt class. You can use this to resolve symbols and ’lisp-ified’ names to Qt class names. Hyphens are stripped from the designator.
See *QT-CLASS-MAP*
class-map.lisp (file)
toolkit.lisp (file)
toolkit.lisp (file)
Attempts to signal the function FUNCTION on OBJECT by determining the
types according to the run-time types of the values.
This is SLOW as the signal method has to be determined at run-time and it
is DANGEROUS as the type mapping are ambiguous or even unknown for certain
arguments and as such the wrong signal may be called or even one that does
not actually exist. If you want to explicitly specify the type of the
argument, wrap it in a CONS where the CAR is the value and the CDR is a
string for the according Qt type.
A compiler macro will try to statically determine types as best as possible, so GENERIC-SIGNAL is save to use for static values.
signal.lisp (file)
Loads all the smoke modules as passed.
See QT:ENSURE-SMOKE
generate.lisp (file)
Returns a fresh list of currently loaded smoke modules.
See QTOOLS:*SMOKE-MODULES*
See QT:NAMED-MODULE-NUMBER
generate.lisp (file)
Transforms CHORD into a keychord string, if possible.
widget-menu.lisp (file)
Wrap the OBJECT in a GC-FINALIZED instance. Use UNBOX to retrieve the object again.
gc-finalized.lisp (file)
Calls FUNCTION with the result of COMPILE-WRAPPER on all available methods.
See QTOOLS:COMPILE-WRAPPER
See QTOOLS:*QMETHODS*
generate.lisp (file)
Map all widgets and layouts on LAYOUT onto FUNCTION.
toolkit.lisp (file)
Deletes the object if possible.
toolkit.lisp (file)
Returns the function to process a menu content type NAME, if any.
widget-menu.lisp (file)
(setf menu-content-type) (function)
Sets the FUNCTION to process menu contents of type NAME.
The function should accept in the very least one argument, which is the symbol of the current parent. The other arguments can be used to decompose the remainder of the content form. Expected are two return values, the first being a form to call during initialization and the second being a form to be run alongside the initializer definition.
widget-menu.lisp (file)
menu-content-type (function)
Returns a function to process the method declaration NAME, if one exists.
See (SETF QTOOLS:METHOD-DECLARATION).
widget-defmethod.lisp (file)
(setf method-declaration) (function)
Sets the FUNCTION to be used to process method declarations of NAME.
The arguments of the function should parse the inner of the declaration.
E.g: (declare (foo bar baz)) could be captured by (a &optional b) with
A=>BAR, B=>BAZ. During evaluation of the function, the special variable
*METHOD* will be bound.
See QTOOLS:*METHOD*.
widget-defmethod.lisp (file)
method-declaration (function)
Returns an appropriate symbol to use for the name of the wrapper function for METHOD.
See QT:QMETHOD-ENUM-P
See QTOOLS:CL-CONSTANT-NAME
See QT:QMETHOD-CTOR-P
See QT:QMETHOD-COPYCTOR-P
See QTOOLS:CL-CONSTRUCTOR-NAME
See QTOOLS:QMETHOD-OPERATOR-P
See QTOOLS:CL-OPERATOR-NAME
See QT:QMETHOD-STATIC-P
See QTOOLS:CL-STATIC-METHOD-NAME
See QTOOLS:CL-METHOD-NAME
generate.lisp (file)
printing.lisp (file)
Clears the method table and generates all possible data for the currently available methods.
This also sets the *GENERATED-MODULES* to the proper value.
See QT:MAP-METHODS
See QTOOLS:PROCESS-METHOD
See QTOOLS:CLEAR-METHOD-INFO
See QTOOLS:*GENERATED-MODULES*
See QTOOLS:LOADED-SMOKE-MODULES
generate.lisp (file)
Push the given METHOD onto its appropriate place in the method table, if it is needed.
See QTOOLS:METHOD-NEEDED-P
See QTOOLS:METHOD-SYMBOL
See QTOOLS:*QMETHODS*
generate.lisp (file)
Writes, compiles, and loads the file for all generated Qt wrapper functions. If MODULES is passed, CommonQt is reloaded and only the given modules are loaded.
See WRITE-EVERYTHING-TO-FILE
precompile.lisp (file)
Searches for Q+ functions that match the term given.
This function is useful to determine the proper converted name for a method or
enum, or to generally discover methods if you cannot recall what it was called
exactly. You can separate terms by a space and only methods that match each
individual term will be shown. Matches are case-insensitive and ignore hyphens
as well as underscores and dots.
Example: (q+apropos "qimage format")
Q+::QIMAGE.FORMAT_INVALID
...
This function calls ENSURE-METHODS-PROCESSED before performing the search to
ensure the method cache is fully populated according to the currently loaded
modules.
See QTOOLS:ENSURE-METHODS-PROCESSED
See QTOOLS:*QMETHODS*
generate.lisp (file)
Returns the class precedence list for the given qclass.
See *QCLASS-PRECEDENCE-LISTS*
See COMPUTE-QCLASS-PRECEDENCE-LIST
dispatch.lisp (file)
Tests whether INSTANCE is an INSTANCE of CLASS.
This includes subclasses, so a QSlider instance is also an instance of a QWidget and so forth.
dispatch.lisp (file)
Returns T if the object is not null and not deleted.
toolkit.lisp (file)
Attempts to determine the proper Qt type descriptor for the passed cl type name.
Look at the source to see the mappings.
name-translation.lisp (file)
Attempts to determine a proper Qt type descriptor for the type of the OBJECT.
Look at the source to see the mappings.
name-translation.lisp (file)
Removes the FINALIZER definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the slot.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes the INITIALIZER definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the slot.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes the menu content type NAME.
widget-menu.lisp (file)
Remove the method declaration processor function of NAME.
widget-defmethod.lisp (file)
Removes the OVERRIDE definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the override.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes the SIGNAL definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the slot.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes the SLOT definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the slot.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes the SUBWIDGET definition from the WIDGET-CLASS.
Note that this does not remove eventual methods associated with the subwidget.
It does however remove the class-slot and initializer of the subwidget.
See QTOOLS:REMOVE-WIDGET-CLASS-OPTION
See QTOOLS:ENSURE-CLASS
widget-convenience.lisp (file)
Removes a CLASS OPTION value.
The value is identified and distinguished within the OPTION list
by TEST on KEY. If the first item in the sub-list is EQUAL to IDENTIFIER,
it is removed. This causes a call to SOFTLY-REDEFINE-WIDGET-CLASS.
See QTOOLS:WIDGET-CLASS-EXTERN-OPTIONS.
See QTOOLS:SOFTLY-REDEFINE-WIDGET-CLASS.
widget.lisp (file)
Sets a CLASS OPTION VALUE.
The value is identified and distinguished within the OPTION list
by TEST on KEY. If a matching list can be found, it is replaced
at the same position. Otherwise it is appended to the end of the
list. The order here is important to preserve load-order.
See QTOOLS:WIDGET-CLASS-EXTERN-OPTIONS.
See QTOOLS:SOFTLY-REDEFINE-WIDGET-CLASS.
widget.lisp (file)
Cause a soft redefinition of the given CLASS.
This will in effect cause a call to REINITIALIZE-INSTANCE with the proper class options added from WIDGET-CLASS-DIRECT-OPTIONS, followed by a FINALIZE-INHERITANCE call on the class.
widget.lisp (file)
Returns a method designator for the FUNCTION and ARGS.
The FUNCTION is transformed as by TO-METHOD-NAME. Each argument type is determined as by TO-TYPE-NAME.
name-translation.lisp (file)
Segregates items in LIST into separate lists if they mach an item in ITEMS.
The first item in the returned list is the list of unmatched items.
Example:
(split ’((0 a) (0 b) (1 a) (1 b) (2 c)) ’(0 2) :key #’car)
=> ’(((1 a) (1 b)) ((0 a) (0 b)) ((2 c)))
toolkit.lisp (file)
Removes all widgets from the layout and finalizes them if so desired.
If FINALIZE is NIL, each widget is removed, its parent set to NIL, and it is hidden as to not show up as a window.
toolkit.lisp (file)
Turns THING into a Qt method name.
If THING is a STRING, it is returned directly.
If THING is a SYMBOL, it is transformed by turning each
character after a hyphen into its uppercase equivalent
and dropping the hyphen. Therefore: foo-bar fooBar
name-translation.lisp (file)
Translates an unsigned-byte 8 vector into a QByteArray.
toolkit.lisp (file)
Returns the type name for THING.
If THING is a string, it is returned directly. If it is a symbol, either QT-TYPE-FOR for THING is returned, or the STRING-DOWNCASE of THING.
name-translation.lisp (file)
Translates the given name to the requested type, if possible.
When ERROR-P is T and no translation can be found, an error is signalled.
Otherwise in that case NIL is returned.
See TRANSLATOR
name-translation.lisp (file)
Returns a list of QAction instances that are active on the given CLASS.
widget-menu.lisp (file)
(setf widget-actions) (function)
Sets the list of QAction instances that are active on the given CLASS.
widget-menu.lisp (file)
widget-actions (function)
Tests if OPTION VALUE is already present on CLASS. Returns the full option value if it can be found.
See QTOOLS:SET-WIDGET-CLASS-OPTION
widget.lisp (file)
Writes all compileable Qt method wrappers to PATHNAME.
PACKAGE designates in which package the symbols will live.
This makes it possible to deviate from the standard of
*TARGET-PACKAGE*. The value of QTOOLS:*TARGET-PACKAGE*
will be automatically set to this once the resulting file
is LOADed or compiled again.
See QTOOLS:WRITE-FORMS
See QTOOLS:*TARGET-PACKAGE*
precompile.lisp (file)
Next: Exported conditions, Previous: Exported functions, Up: Exported definitions [Contents][Index]
widget.lisp (file)
widget.lisp (file)
This method is called during the initialization of a widget instance. It MUST call QT:NEW on the widget at some point. Its primary purpose is to give the user some way to manipulate which arguments are passed to QT:NEW. By default, no arguments are passed.
widget.lisp (file)
Generates a copy of the object.
The way objects are copied varies, but usually it can be assumed that the
copy is made in a way such that data immediately associated with the object
is copied (such as pixel data in an image), but data only implicitly
referenced (such as the paint device of a painter) is not.
Use DESCRIBE-COPY-METHOD for information on a specific copying mechanism.
Uses COPY-QOBJECT-USING-CLASS and determines the class by QT::QOBJECT-CLASS.
copying.lisp (file)
Creates a new GC-Finalized object using the value of COPY on its contained object.
Finalizes the object. The effects thereof may vary and even result in nothing at all.
After FINALIZE has been called on an object, it should not be attempted to be used in any fashion
whatsoever as it may have been rendered unusable or unstable.
This method should be called on any object once it is known that it can be discarded.
FINALIZE will then try to clean up objects and make sure that they don’t clutter your
memory, as lingering QOBJECTs would.
finalizable.lisp (file)
widget.lisp (file)
Finalizes and unbinds all slots on the object that are marked as FINALIZED and then calls the next method.
Calls the next method and then invokes FINALIZE on all items of the list.
Calls the next method and then invokes FINALIZE on all items of the vector.
Calls the next method and then invokes FINALIZE on all the keys and values of the table.
Calls the next method and then invokes MAYBE-DELETE-QOBJECT.
automatically generated reader method
finalizable.lisp (file)
accesses the PARENT of the object. This usually translates to (#_parent object) unless overridden.
toolkit.lisp (file)
(setf parent) (generic function)
parent (generic function)
toolkit.lisp (file)
widget.lisp (file)
automatically generated reader method
gc-finalized.lisp (file)
Accesses the VALUE of the object. This usually translates to (#_value object) unless overridden.
toolkit.lisp (file)
(setf value) (generic function)
widget.lisp (file)
toolkit.lisp (file)
value (generic function)
widget.lisp (file)
Contains all the options passed to RE/INITIALIZE-INSTANCE when the class is re/initialized directly through a DEFCLASS form.
(setf widget-class-direct-options) (generic function)
automatically generated reader method
widget.lisp (file)
widget-class-direct-options (generic function)
automatically generated writer method
widget.lisp (file)
Contains all the options that are added to the class definition through external forms and thus need to be included and kept separate from options directly specified in the class definition.
(setf widget-class-extern-options) (generic function)
automatically generated reader method
widget.lisp (file)
widget-class-extern-options (generic function)
automatically generated writer method
widget.lisp (file)
A sorted list of functions to be called upon finalization.
This list is overwritten completely whenever the class is re/initialized.
See QTOOLS:CALL-FINALIZERS
(setf widget-class-finalizers) (generic function)
automatically generated reader method
widget.lisp (file)
widget-class-finalizers (generic function)
automatically generated writer method
widget.lisp (file)
A sorted list of functions to be called upon initialization.
This list is overwritten completely whenever the class is re/initialized.
See QTOOLS:CALL-INITIALIZERS
(setf widget-class-initializers) (generic function)
automatically generated reader method
widget.lisp (file)
widget-class-initializers (generic function)
automatically generated writer method
widget.lisp (file)
Next: Exported classes, Previous: Exported generic functions, Up: Exported definitions [Contents][Index]
toolkit.lisp (file)
compiler-note (condition)
:message
(quote (error "message required."))
message (generic function)
(setf message) (generic function)
widget.lisp (file)
error (condition)
:requested-qt-superclass
requested-qt-superclass (generic function)
(setf requested-qt-superclass) (generic function)
:clashing-qt-superclass
clashing-qt-superclass (generic function)
(setf clashing-qt-superclass) (generic function)
:clashing-superclass
clashing-superclass (generic function)
(setf clashing-superclass) (generic function)
Next: Exported types, Previous: Exported conditions, Up: Exported definitions [Contents][Index]
A class for finalizable objects.
finalizable.lisp (file)
standard-object (class)
finalize (method)
Metaclass for classes with finalizable slots.
finalizable.lisp (file)
standard-class (class)
widget-class (class)
Superclass for slots with a finalized option.
finalizable.lisp (file)
standard-object (class)
:finalized
finalized (generic function)
Wrapper object to allow automatic calling of FINALIZE by the GC.
Since you cannot finalize the object that is GC-ed itself, we need to wrap our to-
be-finalized object in another object that takes all the references instead.
This means that if you wish your object to remain unfinalized, you need to retain
references to the wrapper. As soon as the wrapper is hit by the GC, FINALIZE is
called on the object it contains.
In order to retrieve the contained object, use UNBOX.
gc-finalized.lisp (file)
finalizable (class)
:object
(error "object required.")
unbox (generic function)
A DEPLOY:DEPLOY-OP subclass to handle things for Qt deployment.
You should specify this as the BUILD-OPERATION in your ASD along with an ENTRY-POINT and a BUILD-PATHNAME.
deploy.lisp (file)
deploy-op (class)
Common superclass for all widgets in order to allow for
general initialization and cleanup forms that are standardised across all
widgets.
See QTOOLS:DEFINE-WIDGET.
widget.lisp (file)
Metaclass for widgets storing necessary information.
The metadata stored in this is mostly responsible for two things:
1) Providing access to a sequence of mutually independent
initializers and finalizers for convenient setup and cleanup.
2) Allowing after-the-fact out-of-form changes to the class
definition, which is necessary to have for a distributed
definition form syntax as provided by WIDGET-CONVENIENCE macros.
In order to modify the metadata, please look at SET/REMOVE-WIDGET-CLASS-OPTION.
widget.lisp (file)
widget-class-direct-options (generic function)
(setf widget-class-direct-options) (generic function)
widget-class-extern-options (generic function)
(setf widget-class-extern-options) (generic function)
:initializers
widget-class-direct-initializers (generic function)
(setf widget-class-direct-initializers) (generic function)
:finalizers
widget-class-direct-finalizers (generic function)
(setf widget-class-direct-finalizers) (generic function)
widget-class-initializers (generic function)
(setf widget-class-initializers) (generic function)
widget-class-finalizers (generic function)
(setf widget-class-finalizers) (generic function)
Previous: Exported classes, Up: Exported definitions [Contents][Index]
dynamic.lisp (file)
Previous: Exported definitions, Up: Definitions [Contents][Index]
• Internal special variables: | ||
• Internal macros: | ||
• Internal functions: | ||
• Internal generic functions: | ||
• Internal conditions: | ||
• Internal classes: |
Next: Internal macros, Previous: Internal definitions, Up: Internal definitions [Contents][Index]
toolkit.lisp (file)
widget-menu.lisp (file)
widget-defmethod.lisp (file)
copying.lisp (file)
finalizable.lisp (file)
dispatch.lisp (file)
Holds a map of computed precedence lists for qclasses.
We can cache this since the Qt class hierarchy is static.
dispatch.lisp (file)
printing.lisp (file)
dynamic.lisp (file)
dynamic.lisp (file)
An ordered list of name translators.
See TRANSLATOR
See REMOVE-TRANSLATOR
name-translation.lisp (file)
widget-menu.lisp (file)
Next: Internal functions, Previous: Internal special variables, Up: Internal definitions [Contents][Index]
Shorthand for EXPORT, DECLAIM INLINE, and DEFUN.
generate.lisp (file)
Shorthand for EXPORT and DEFMACRO.
generate.lisp (file)
copying.lisp (file)
finalizable.lisp (file)
printing.lisp (file)
generate.lisp (file)
toolkit.lisp (file)
printing.lisp (file)
Calculates the proper argument list parts required for the given METHODS.
generate.lisp (file)
Compiles BODY in a lambda and funcalls it.
toolkit.lisp (file)
Same as WITH-OUTPUT-TO-STRING, but the result is translated to a *TARGET-PACKAGE* symbol.
See QTOOLS:TARGET-SYMBOL
See CL:WITH-OUTPUT-TO-STRING
generate.lisp (file)
toolkit.lisp (file)
Next: Internal generic functions, Previous: Internal macros, Up: Internal definitions [Contents][Index]
finalizable.lisp (file)
name-translation.lisp (file)
widget-convenience.lisp (file)
generate.lisp (file)
name-translation.lisp (file)
widget.lisp (file)
Check whether the given QT-SUPERCLASS is permissible given the DIRECT-SUPERCLASSES.
widget.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
Returns a cleaned up name of METHOD.
This effectively trims #, $, and ? from the name.
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
generate.lisp (file)
Calculates the class precedence list for the given qclass as per CLHS 4.3.5
dispatch.lisp (file)
generate.lisp (file)
toolkit.lisp (file)
toolkit.lisp (file)
toolkit.lisp (file)
Attempts to return the list of methods associated with METHOD.
METHOD can be a SYMBOL, LIST, FIXNUM, or STRING.
If no methods can be found in the method table, an error is signalled.
generate.lisp (file)
Generates a docstring for an enum constant.
generate.lisp (file)
Generates a docstring that references all the Qt methods that a wrapper function can be used for.
generate.lisp (file)
Generates a named-lambda form suitable for usage in a qclass-method.
Specifically, it establishes the appropriate local NEXT-METHOD-P and CALL-NEXT-METHOD functions within the lambda body. Both of them behave exactly like the CLOS ones do– NEXT-METHOD-P returns T if there is a next method that can be dispatched to, and CALL-NEXT-METHOD calls this method if it exists or calls NO-NEXT-METHOD if it does not exist.
dispatch.lisp (file)
toolkit.lisp (file)
readtable.lisp (file)
If it is a quote form, unwraps the contents. Otherwise returns it directly.
toolkit.lisp (file)
Returns T if the METHOD is considered to be useful for wrapper compilation.
generate.lisp (file)
finalizable.lisp (file)
signal.lisp (file)
Processes a PLACE and VALUE pair for a Q+ setter call. PLACE should be a form calling the Q+ macro, or a form calling a symbol in the *TARGET-PACKAGE* directly. The name of the function being called is prefixed with "SET-", and is then used to form the function name for the resulting Q+ call. If the VALUE is a VALUES form, then all the parts of values are used as individual arguments in the resulting Q+ call.
Example: (process-q+-setter ’(q+ foo 0 1) ’(values 2 3))
=> (q+ "FOO" 0 1 2 3)
See QTOOLS:Q+
See CL+QT:SETF
See QTOOLS:*TARGET-PACKAGE*
dynamic.lisp (file)
dynamic.lisp (file)
dynamic.lisp (file)
Returns a list containing the given class and all of its transient superclasses.
dispatch.lisp (file)
copying.lisp (file)
finalizable.lisp (file)
Builds a class precedence set for the class and all of its transient superclasses.
dispatch.lisp (file)
printing.lisp (file)
Returns T if the METHOD is bogus and unneeded.
generate.lisp (file)
Returns T if the METHOD is a casting operator.
generate.lisp (file)
Returns T if the method is from the QGlobalSpace class.
generate.lisp (file)
Returns T if the METHOD is an operator.
generate.lisp (file)
Returns T if the operator METHOD is one that can be compiled by Qtools.
generate.lisp (file)
Test whether the given CFFI library is a Qtools library.
deploy.lisp (file)
dynamic.lisp (file)
dynamic.lisp (file)
dynamic.lisp (file)
dynamic.lisp (file)
copying.lisp (file)
finalizable.lisp (file)
printing.lisp (file)
Removes the translator by the given name.
See TRANSLATOR
See *TRANSLATORS*
name-translation.lisp (file)
class-map.lisp (file)
widget.lisp (file)
This function should not be called directly, but is instead invoked by the appropriate functions such as INITIALIZE-INSTANCE, REINITIALIZE-INSTANCE, and SOFTLY-REDEFINE-WIDGET-CLASS. In brief, it concerns itself with proper option merging and filtering before passing it on to the CommonQt and CLOS methods that process them.
widget.lisp (file)
signal.lisp (file)
widget-defmethod.lisp (file)
Returns T if the STRING starts with START.
Strings are compared using STRING=
generate.lisp (file)
name-translation.lisp (file)
widget-convenience.lisp (file)
dynamic.lisp (file)
Returns a symbol from the *TARGET-PACKAGE* whose name is formed by
FORMAT-STRING and FORMAT-ARGS.
See QTOOLS:*TARGET-PACKAGE*
See CL:INTERN
See CL:FORMAT
generate.lisp (file)
Translates STRING to the requested reading case according to CASE.
See CL:READTABLE-CASE
dynamic.lisp (file)
Accessor to retrieve or update/add a translator function.
The SETF variant takes an additional, optional argument that sets the translator’s priority.
Higher priority numbers get considered first.
See TRANSLATOR
See REMOVE-TRANSLATOR
See DEFINE-TRANSLATOR
See *TRANSLATORS*
name-translation.lisp (file)
(setf translator) (function)
name-translation.lisp (file)
translator (function)
Writes all compileable forms to STREAM.
See QTOOLS:MAP-COMPILE-ALL
precompile.lisp (file)
Writes an appropriate translation of the QCLASS’ name to STREAM.
Translation is as follows:
For every character, its uppercase equivalent is printed to stream,
with the exception of #: which is printed as a #-. Any number of
succeeding #: s is translated to a single #-.
KLUDGE: This approach does not currently take the readtable case into account. This will be problematic on systems where it matters.
See CL:CHAR-UPCASE
generate.lisp (file)
Writes an appropriate translation of the QMETHOD’s name to STREAM.
Translation is as follows:
If an uppercase alphabetic character is encountered and the previous
character was not already uppercase, #- is printed. If #_ is
encountered, it is treated as an uppercase character and printed
as #_. A #- would be more "lispy" to use for a #_, but doing so
leads to method name clashes (most notably "set_widget" and
"setWidget"). Any other character is printed as their uppercase
equivalent.
KLUDGE: This approach does not currently take the readtable case into account. This will be problematic on systems where it matters.
See CL:CHAR-UPCASE
generate.lisp (file)
Next: Internal conditions, Previous: Internal functions, Up: Internal definitions [Contents][Index]
toolkit.lisp (file)
automatically generated reader method
name-translation.lisp (file)
automatically generated writer method
name-translation.lisp (file)
automatically generated reader method
name-translation.lisp (file)
automatically generated writer method
name-translation.lisp (file)
automatically generated reader method
name-translation.lisp (file)
automatically generated writer method
name-translation.lisp (file)
automatically generated reader method
widget.lisp (file)
automatically generated writer method
widget.lisp (file)
automatically generated reader method
widget.lisp (file)
automatically generated writer method
widget.lisp (file)
Next: Internal classes, Previous: Internal generic functions, Up: Internal definitions [Contents][Index]
name-translation.lisp (file)
style-warning (condition)
:type-name
Previous: Internal conditions, Up: Internal definitions [Contents][Index]
finalizable.lisp (file)
finalizable.lisp (file)
Translator data type class holding the name, priority, and translation function.
See TRANSLATOR
name-translation.lisp (file)
standard-object (class)
:name
name (generic function)
(setf name) (generic function)
:translation
translation (generic function)
(setf translation) (generic function)
:priority
priority (generic function)
(setf priority) (generic function)
Initarg | Value |
---|---|
:name | (error "name required.") |
:translation | (error "translation required.") |
:priority | 0 |
Previous: Definitions, Up: Top [Contents][Index]
• Concept index: | ||
• Function index: | ||
• Variable index: | ||
• Data type index: |
Next: Function index, Previous: Indexes, Up: Indexes [Contents][Index]
Jump to: | F L Q |
---|
Jump to: | F L Q |
---|
Next: Variable index, Previous: Concept index, Up: Indexes [Contents][Index]
Jump to: | %
(
B C D E F G L M N P Q R S T U V W |
---|
Jump to: | %
(
B C D E F G L M N P Q R S T U V W |
---|
Next: Data type index, Previous: Function index, Up: Indexes [Contents][Index]
Jump to: | %
*
C D E F I M N P R S T |
---|
Jump to: | %
*
C D E F I M N P R S T |
---|
Previous: Variable index, Up: Indexes [Contents][Index]
Jump to: | C F G I P Q S T U W |
---|
Jump to: | C F G I P Q S T U W |
---|