A simple example using Qt Signals and Slots is as follows:
module Main where import Qtc.Classes.Qccs import Qtc.Classes.Gui import Qtc.ClassTypes.Gui import Qtc.Core.Base import Qtc.Gui.Base import Qtc.Gui.QApplication import Qtc.Gui.QWidget import Qtc.Gui.QPushButton import Qtc.Gui.QAbstractButton import Qtc.Gui.QMessageBox type MyQPushButton = QPushButtonSc (CMyQPushButton) data CMyQPushButton = CMyQPushButton myQPushButton :: String -> IO (MyQPushButton) myQPushButton b = qSubClass $ qPushButton b main :: IO Int main = do qApplication () hello <- myQPushButton "Hello qtHaskell World" resize hello (200::Int, 60::Int) mb <- qMessageBox hello connectSlot hello "clicked()" hello "click()" $ on_hello_clicked mb qshow hello () qApplicationExec () on_hello_clicked :: QMessageBox () -> MyQPushButton -> IO () on_hello_clicked mb this = do tt <- text this () setText mb $ "You have clicked " ++ tt qshow mb ()
Slots are connected to Signals using the connectSlot
statement. This has the general format:
connectSlot
signal_object "signal_signature" slot_object "slot_signature" slot_function
Both the signal_object
and slot_object
must be previously declared Qt objects.
The "signal_signature"
and
"slot_signature"
strings describe the name and parameter types
of the signal and slot to be connected. The parameter types must be the same
for both strings.
The slot_function
is a partial application
of a Haskell function of type:
global_Haskell_parameters -> slot_object_type -> slot_parameters
Both the signal and slot can be "built in" signal/slots of their
respective Qt classes, or custom signal/slots, in which case there is no
need to declare them prior to use in a connectSlot
statement. If the slot is a "built in" slot of the Qt
slot_object
class, no slot_function
is required but the connectSlot
statement must still be
terminated by an empty pair of parentheses.
Signals can be connected to other signals using the
connectSignal
statement. This has the general format:
connectSignal
first_signal_object "first_signal_signature" second_signal_object "second_signal_signature"
In all the above cases the format of signal/slot signature strings is same as for the SIGNAL and SLOT macros used in C++ Qt programs.
If custom signals or slots are required for a class, the class must be
subclassed. This is a two stage process. Firstly, create a new shadow type
based on the Qt class to be subclassed, then create a constructor (or
constructor class) that uses qSubClass
to call the
constructor of the base class.
In the above example we see how to subclass the Qt class "QPushButton" to create a custom slot "click()". This has the general formula:
type
MySubClassType
= QBaseClassType
Sc (CMySubClassType
)
data
CMySubClassType
= CMySubClassType
mySubClassType
:: p1Type -> p2Type ...
-> IO (MySubClassType
)
mySubClassType
p1 p2 ...
= qSubClass $ qBaseClasstype p1 p2 ...
N.B. If a "built-in" signal is connected to a custom slot on a different object, the signal object does not have to be subclassed. This is very useful for menus and menubars where we have many objects of type QAction which can connect their "built-in" signal "triggered()" to custom slots on the main application widget object, without having to be subclassed.