Very complete bindings to both the KDE API and the Qt APIs. The Korundum package includes both a QtRuby Qt-only binding along with the full combined Qt/KDE one. The QtRuby package contains just Qt bindings with no dependencies on KDE.

Constructors

The block will be called in the context of the newly created instance.

Ordinary arguments can be provided as well as a block at the end:

w = MyWidget.new(nil) { setCaption("foobar") }

They are run in the context of the new instance.

And there's more! You can also pass an arg to the block, and it will be run in the context of the arg:

w = MyWidget.new { |theWidget| theWidget.setCaption "foobar" }

Garbage Collection

When a ruby instance is garbage collected, the underlying C++ instance will only be deleted if it isn't 'owned' by a parent object. Normally this will 'just work', but there are occasions when you need to delete the C++ ahead of garbage collection, and whether or not it has a parent. Use the dispose(), isDisposed() and disposed? methods like this:

item2.dispose
if item2.disposed?
puts "item2 is disposed"
end

C++ 'int*' and 'int&' argument types

Ruby passes numeric values by value, and so they can't be changed when passed to a method. The Qt::Integer class provides a mutable numeric type which does get updated when passed as an argument. For example, this C++ method 'findByFileContent()':

Another debugging mechanism allows various trace 'channels' to be switched on.

You can trace virtual method callbacks:

Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_VIRTUAL)

Or trace QtRuby garbage collection:

Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_GC)

String i18n

QtRuby supports $KCODE values of 'u', 'e' and 's' or the corresponding '-K' options from the command line. Qt Designer .ui files have UTF-8 strings so if you use any 8 bit UTF-8 characters, you will need to set $KCODE='u' or use the -Ku command line option.

Other capabilities and offerings

Qt Designer

A 'rbuic' tool is included in qtruby/rubylib/designer/rbuic to compile .ui files into ruby code. As described above, Qt Designer uses UTF-8. In addition to the options in the original uic C++ utility an '-x' flag has been added. This will generate a top level stub in the code:

QtRuby shell

You can use the QtRuby shell in bin/rbqtsh to create widgets interactively from the command line.

API reference

Use the bin/rbqtapish tool to discover which methods are available in the QtRuby api. This command:

$ rbqtapish Qt::TextEdit

Will list all the methods in the Qt::TextEdit class

$ rbqtapi -rsetCaption

Lists all methods whose names contain the string 'setCaption'

Example programs

The best way to start programming QtRuby is to look at some existing code and start messing with it.. The are various samples under qtruby/rubylib/examples and korundum/rubylib/examples.

KDE Specific Infomation

Instead of require 'Qt', use require 'Korundum' for KDE programs.

The KDE K* classes such as KApplication are renamed as KDE::Application. The other KDE classes are in the KParts::, KIO:: or DOM:: namespaces, with the same names as their C++ counterparts.

Use the 'rbkdeapi' script to introspect the Korundum api from the command line. For example:

$ rbkdeapi KDE::Action

Will list all the methods in the KDE::Action class. There are currently (as at KDE 3.3 beta 2) 977 classes/30841 methods in the Smoke library runtime, so the coverage of the Qt/KDE api is pretty complete.

Note that the class doesn't have to inherit from DCOPObject. If you include a 'k_dcop' slots declaration a 'listener' dcop object instance is created automatically, and these four methods are added to your class:

interfaces()
functions()
connectDCOPSignal()
disconnectDCOPSignal()

The name of the object is always the ruby classname, and you can only instantiate one instance for each ruby class that has 'k_dcop' declarations. See examples/dcop/dcopslot.rb and dcopsignal.rb for an example of the simplest approach.

If you wish to use the full functionality of a DCOPObject, you can subclass it and call all the methods, not just the four above. Additionally, you can instantiate more than one instance per class and rename the dcop object with the setObjId() method or by passing the name to the constructor. See the examples/dcop/petshop.rb code for an example of a more complex dcop object.

Amaze your friends! Do the programming equivalent of leaping over tall buildings in one bound! Here with one line of quite clear code, we read a file from disc and assign it the 'clipboardContents' klipper attribute via dcop:

klipper.clipboardContents = IO.readlines("myfile").to_s

DCOP Predicates

Instead of:

result = dcopRef.isFoo()

You can use this more rubyish form:

if dcopRef.foo?
puts "foo is true"
else
puts "foo? is false"
end

Similarly you can use foo? as an alias for methods of the form hasFoo(). See examples/dcop/dcoppredicate.rb and dcopslot.rb

Underscore to CamelCase DCOP method name conversion

Any underscores in a method name are removed, and the following character is capitalised. For example:

Send to a DCOPRef

The result will either be true or false (but not nil for fail like DCOPRef.call() method described above).

When a call of the form 'dcopRef.getPoint(5, "foobar")' is made, the C++ type signature is obtained from the list of those returned by DCOPRef.functions(). However, if a method name is overloaded the ruby argument types are used to derive a type signature, in order to resolve the call like this: