Languages/Ruby: Difference between revisions
(announcement Ruby-Qt/KDE book) |
No edit summary |
||
Line 12: | Line 12: | ||
= QtRuby = | = QtRuby = | ||
Hello world example: | Hello world example: | ||
<code> | <code ruby> | ||
#!/usr/bin/ruby -w | #!/usr/bin/ruby -w | ||
require 'Qt4' | require 'Qt4' | ||
Line 24: | Line 24: | ||
Hello Qt example in a more 'Rubyish' way: | Hello Qt example in a more 'Rubyish' way: | ||
<code> | <code ruby> | ||
require 'Qt4' | require 'Qt4' | ||
Line 49: | Line 49: | ||
exec | exec | ||
end | end | ||
</code> | </code> | ||
Line 65: | Line 64: | ||
Any underscores in method names are removed, and the following character is capitalised. For example, you can use either of these two forms to call the same method: | Any underscores in method names are removed, and the following character is capitalised. For example, you can use either of these two forms to call the same method: | ||
<code ruby> | |||
create_standard_status_bar_action() | |||
createStandardStatusBarAction() | |||
</code> | |||
==Operator overloading== | ==Operator overloading== | ||
The full range of Qt operator methods is available, for example: | The full range of Qt operator methods is available, for example: | ||
<code ruby> | |||
p1 = Qt::Point.new(5,5) => (5, 5) | |||
p2 = Qt::Point.new(20,20) => (20, 20) | |||
p1 + p2 => (25, 25) | |||
</code> | |||
==Declare signals and slots== | ==Declare signals and slots== | ||
Signals and slots are declared as list of strings like this: | Signals and slots are declared as list of strings like this: | ||
<code ruby> | |||
slots 'setColor(QColor)', 'slotLoad(const QString&)'.. | |||
signals 'clicked()'.. | |||
</code> | |||
For slots and signals without arguments you can use Ruby symbols: | For slots and signals without arguments you can use Ruby symbols: | ||
<code ruby> | |||
slots :slotLoad | |||
signals :clicked | |||
</code> | |||
Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead. | Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead. | ||
Connect slots and signals like this: | Connect slots and signals like this: | ||
<code ruby> | |||
Qt::Object.connect( @colormenu, SIGNAL( "activated(int)" ), | |||
self, SLOT( "slotColorMenu(int)" ) ) | |||
</code> | |||
Or you can connect signal to a block: | Or you can connect signal to a block: | ||
<code ruby> | |||
quit_button.connect(SIGNAL :clicked) { $qApp.quit } | |||
</code> | |||
And emit signals like this: | And emit signals like this: | ||
<code ruby> | |||
emit colorChanged( black ) | |||
</code> | |||
==Constructors== | ==Constructors== | ||
You can call constructors in the conventional style: | You can call constructors in the conventional style: | ||
<code ruby> | |||
quit = Qt::PushButton.new("Quit", self, "quit") | |||
</code> | |||
Or you can pass a block if you prefer: | Or you can pass a block if you prefer: | ||
<code ruby> | |||
w = MyWidget.new { setCaption("foobar") } | |||
</code> | |||
The block will be called in the context of the newly created instance. | The block will be called in the context of the newly created instance. | ||
Line 117: | Line 132: | ||
Ordinary arguments can be provided as well as a block at the end: | Ordinary arguments can be provided as well as a block at the end: | ||
<code ruby> | |||
w = MyWidget.new(nil) { setCaption("foobar") } | |||
</code> | |||
They are run in the context of the new instance. | They are run in the context of the new instance. | ||
Line 123: | Line 140: | ||
And there's more! You can also pass an arg to the block, and it will be run in the context of the arg: | And there's more! You can also pass an arg to the block, and it will be run in the context of the arg: | ||
<code ruby> | |||
w = MyWidget.new { |theWidget| theWidget.setCaption "foobar" } | |||
</code> | |||
==Garbage Collection== | ==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: | 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: | ||
<code ruby> | |||
item2.dispose | |||
if item2.disposed? | |||
puts "item2 is disposed" | |||
end | |||
</code> | |||
==C++ 'int*' and 'int&' argument types== | ==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()': | 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()': | ||
<code ruby> | |||
# static Ptr findByFileContent( const QString &fileName, | |||
# int *accuracy=0 ); | |||
acc = Qt::Integer.new(0) | |||
fc = KDE::MimeType.findByFileContent("mimetype.rb", acc) | |||
</code> | |||
It supports the arithmetic operators, and so expressions such as 'acc + 3' will work. | It supports the arithmetic operators, and so expressions such as 'acc + 3' will work. | ||
==C++ 'bool*' and 'bool&' argument types== | ==C++ 'bool*' and 'bool&' argument types== | ||
There is a similar problem for bool arg types, and the mutable Qt::Boolean class can be used like this: | There is a similar problem for bool arg types, and the mutable Qt::Boolean class can be used like this: | ||
<code ruby> | |||
# QFont getFont(bool * ok, const QFont&initial, | |||
# QWidget* parent = 0, const char *name = 0); | |||
ok = Qt::Boolean.new | |||
font = Qt::FontDialog.getFont(ok, | |||
Qt::Font.new("Helvetica [Cronyx]", 10), | |||
self) | |||
if !ok.nil? | |||
# font is set to the font the user selected | |||
else | |||
# the user canceled the dialog | |||
end | |||
</code> | |||
Use 'nil?' to test the value returned in the Boolean | Use 'nil?' to test the value returned in the Boolean | ||
==C++ (const )(unsigned )char* argument types== | ==C++ (const )(unsigned )char* argument types== | ||
In some cases Qt/KDE object "takes ownership" over Ruby String passed as char* argument type. Programmer needs to make sure that Ruby String is not being garbage collected or changed for the time it's being used by Qt/KDE object. It is also quite possible that Qt/KDE object will change and eventually free it(memory used internally by Ruby String to store its data). Be very careful when you call this kind of methods and make sure that there is no overloaded version witch accepts QString or QByteArray first! | In some cases Qt/KDE object "takes ownership" over Ruby String passed as char* argument type. Programmer needs to make sure that Ruby String is not being garbage collected or changed for the time it's being used by Qt/KDE object. It is also quite possible that Qt/KDE object will change and eventually free it(memory used internally by Ruby String to store its data). Be very careful when you call this kind of methods and make sure that there is no overloaded version witch accepts QString or QByteArray first! | ||
Line 175: | Line 195: | ||
==Debugging== | ==Debugging== | ||
If a method call can't be matched in the Smoke library giving a 'method_missing' error, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also turn on debugging to trace the matching process: | If a method call can't be matched in the Smoke library giving a 'method_missing' error, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also turn on debugging to trace the matching process: | ||
<code ruby> | |||
a = Qt::Application.new(ARGV) | |||
Qt.debug_level = Qt::DebugLevel::High | |||
a.loadLibrary("foo") # Non existent method | |||
</code> | |||
Will give the following output: | Will give the following output: | ||
Line 191: | Line 212: | ||
static QWidget* QApplication::widgetAt(int, int, bool) | static QWidget* QApplication::widgetAt(int, int, bool) | ||
... | ... | ||
Here, the list of candidate methods 'methodIds' is empty | Here, the list of candidate methods 'methodIds' is empty | ||
Line 197: | Line 219: | ||
You can trace virtual method callbacks: | You can trace virtual method callbacks: | ||
<code ruby> | |||
Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_VIRTUAL) | |||
</code> | |||
Or trace QtRuby garbage collection: | Or trace QtRuby garbage collection: | ||
<code ruby> | |||
Qt::Internal::setDebug(Qt::QtDebugChannel::QTDB_GC) | |||
</code> | |||
==String i18n== | ==String i18n== | ||
Line 210: | Line 236: | ||
==Qt Designer== | ==Qt Designer== | ||
A 'rbuic4' tool is included in qtruby/tools/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: | A 'rbuic4' tool is included in qtruby/tools/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: | ||
<code bash> | |||
$ rbuic mainform.ui -x -o mainform.rb | |||
</code> | |||
Will add this to the end of the generated code: | Will add this to the end of the generated code: | ||
<code ruby> | |||
if $0 == __FILE__ | |||
a = Qt::Application.new(ARGV) | |||
w = MainForm.new | |||
w.show | |||
a.exec | |||
end | |||
</code> | |||
Then you can test the example code straight away: | Then you can test the example code straight away: | ||
Line 230: | Line 259: | ||
Use the '-kde' option to require the 'korundum4' extension rather than the 'Qt4' one. If the '-x' option is used in conjunction, it generates a KDE top level. For example: | Use the '-kde' option to require the 'korundum4' extension rather than the 'Qt4' one. If the '-x' option is used in conjunction, it generates a KDE top level. For example: | ||
<code bash> | |||
$ rbuic4 -x -kde knotifywidgetbase.ui -o knotifywidgetbase.rb | |||
</code> | |||
Will generate this top level code: | Will generate this top level code: | ||
<code ruby> | |||
if $0 == __FILE__ | |||
about = KDE::AboutData.new("knotifywidgetbase", | |||
"KNotifyWidgetBase", "0.1") | |||
KDE::CmdLineArgs.init(ARGV, about) | |||
a = KDE::Application.new() | |||
w = KNotifyWidgetBase.new | |||
w.show | |||
a.exec | |||
end | |||
</code> | |||
==Loading .ui files at runtime with Qt::UILoader== | ==Loading .ui files at runtime with Qt::UILoader== | ||
Line 299: | Line 332: | ||
Use the bin/rbqtapi tool to discover which methods are available in the QtRuby api. This command: | Use the bin/rbqtapi tool to discover which methods are available in the QtRuby api. This command: | ||
<code bash> | |||
$ rbqtapi Qt::TextEdit | |||
</code> | |||
Will list all the methods in the Qt::TextEdit class | Will list all the methods in the Qt::TextEdit class | ||
<code bash> | |||
$ rbqtapi -rsetCaption | |||
</code> | |||
Lists all methods whose names contain the string 'setCaption' | Lists all methods whose names contain the string 'setCaption' | ||
Line 312: | Line 349: | ||
=KDE Specific Infomation= | =KDE Specific Infomation= | ||
Instead of <code ruby>require 'Qt4'</code>, use<code ruby>require 'korundum4'</code> for KDE programs. | |||
Instead of <code>require 'Qt4'</code>, use <code>require 'korundum4'</code> 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. | 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. | ||
Line 319: | Line 355: | ||
Use the 'rbkdeapi' script to introspect the Korundum api from the command line. For example: | Use the 'rbkdeapi' script to introspect the Korundum api from the command line. For example: | ||
<code bash> | |||
$ rbkdeapi KDE::Action | |||
</code> | |||
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. | 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. | ||
Line 331: | Line 369: | ||
=Tutorials= | =Tutorials= | ||
There is a ruby translation of [http://developer.kde.org/language-bindings/ruby/tutorial/tutorial.html Qt Tutorial #1], and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14. | There is a ruby translation of [http://developer.kde.org/language-bindings/ruby/tutorial/tutorial.html Qt Tutorial #1], and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14. | ||
Revision as of 01:39, 18 January 2010
Development/Languages/Ruby
Languages: عربي | Asturianu | Català | Česky | Kaszëbsczi | Dansk | Deutsch | English | Esperanto | Español | Eesti | فارسی | Suomi | Français | Galego | Italiano | 日本語 | 한국어 | Norwegian | Polski | Português Brasileiro | Română | Русский | Svenska | Slovenčina | Slovenščina | српски | Türkçe | Tiếng Việt | Українська | 简体中文 | 繁體中文
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.
Korundum/QtRuby - Ruby-KDE/Qt bindings
The book Rapid GUI Development with QtRuby (for Qt version 3.x) is available.
Being Smoke-based bindings means that they offer full access to most KDE 4.x and Qt 4.x classes.
QtRuby
Hello world example:
- !/usr/bin/ruby -w
require 'Qt4'
a = Qt::Application.new(ARGV)
hello = Qt::PushButton.new("Hello World!")
hello.resize(100, 30)
hello.show
a.exec
Hello Qt example in a more 'Rubyish' way:
require 'Qt4'
Qt::Application.new(ARGV) do
Qt::Widget.new do
self.window_title = 'Hello QtRuby v1.0'
resize(200, 100)
button = Qt::PushButton.new('Quit') do
connect(SIGNAL :clicked) { Qt::Application.instance.quit }
end
label = Qt::Label.new('Hello Qt in the Ruby way!')
self.layout = Qt::VBoxLayout.new do
add_widget(label, 0, Qt::AlignCenter)
add_widget(button, 0, Qt::AlignRight)
end
show
end
exec
end
Current api coverage overview
Available calls
You can call all Qt public and protected methods, and all friend methods such as bitBlt() etc
Virtual methods
All virtual methods can be overridden, not just event handlers
Properties
'foobar = 5' is a synonym for 'setFooBar(5)'
Use either CamelCase or lowercase with underscore naming
Any underscores in method names are removed, and the following character is capitalised. For example, you can use either of these two forms to call the same method:
create_standard_status_bar_action()
createStandardStatusBarAction()
Operator overloading
The full range of Qt operator methods is available, for example:
p1 = Qt::Point.new(5,5) => (5, 5)
p2 = Qt::Point.new(20,20) => (20, 20)
p1 + p2 => (25, 25)
Declare signals and slots
Signals and slots are declared as list of strings like this:
slots 'setColor(QColor)', 'slotLoad(const QString&)'..
signals 'clicked()'..
For slots and signals without arguments you can use Ruby symbols:
slots :slotLoad
signals :clicked
Currently C++ type signatures must be used, a future version of QtRuby will allow ruby type signatures instead.
Connect slots and signals like this:
Qt::Object.connect( @colormenu, SIGNAL( "activated(int)" ),
self, SLOT( "slotColorMenu(int)" ) )
Or you can connect signal to a block:
quit_button.connect(SIGNAL :clicked) { $qApp.quit }
And emit signals like this:
emit colorChanged( black )
Constructors
You can call constructors in the conventional style:
quit = Qt::PushButton.new("Quit", self, "quit")
Or you can pass a block if you prefer:
w = MyWidget.new { setCaption("foobar") }
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()':
- static Ptr findByFileContent( const QString &fileName,
- int *accuracy=0 );
acc = Qt::Integer.new(0)
fc = KDE::MimeType.findByFileContent("mimetype.rb", acc)
It supports the arithmetic operators, and so expressions such as 'acc + 3' will work.
C++ 'bool*' and 'bool&' argument types
There is a similar problem for bool arg types, and the mutable Qt::Boolean class can be used like this:
- QFont getFont(bool * ok, const QFont&initial,
- QWidget* parent = 0, const char *name = 0);
ok = Qt::Boolean.new
font = Qt::FontDialog.getFont(ok,
Qt::Font.new("Helvetica [Cronyx]", 10),
self)
if !ok.nil?
- font is set to the font the user selected
else
- the user canceled the dialog
end
Use 'nil?' to test the value returned in the Boolean
C++ (const )(unsigned )char* argument types
In some cases Qt/KDE object "takes ownership" over Ruby String passed as char* argument type. Programmer needs to make sure that Ruby String is not being garbage collected or changed for the time it's being used by Qt/KDE object. It is also quite possible that Qt/KDE object will change and eventually free it(memory used internally by Ruby String to store its data). Be very careful when you call this kind of methods and make sure that there is no overloaded version witch accepts QString or QByteArray first!
C++ unsigned char* functions
Very few functions (as QImage::bits()) return a uchar* to directly manipulate data. These functions are not supported in Ruby and will throw an ArgumentError. More information on the mail list.
Debugging
If a method call can't be matched in the Smoke library giving a 'method_missing' error, first check that you are passing correct class instance that is properly initialized (with super method called in constructors of custom Qt classes descendants). You can also turn on debugging to trace the matching process:
a = Qt::Application.new(ARGV)
Qt.debug_level = Qt::DebugLevel::High
a.loadLibrary("foo") # Non existent method
Will give the following output:
classname == QApplication :: method == loadLibrary$ -> methodIds == [] candidate list: Possible prototypes: static QWidget* QApplication::widgetAt(int, int, bool) ...
Here, the list of candidate methods 'methodIds' is empty
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 'rbuic4' tool is included in qtruby/tools/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:
$ rbuic mainform.ui -x -o mainform.rb
Will add this to the end of the generated code:
if $0 == __FILE__
a = Qt::Application.new(ARGV)
w = MainForm.new
w.show
a.exec
end
Then you can test the example code straight away:
$ ruby mainform.rb
Use the '-kde' option to require the 'korundum4' extension rather than the 'Qt4' one. If the '-x' option is used in conjunction, it generates a KDE top level. For example:
$ rbuic4 -x -kde knotifywidgetbase.ui -o knotifywidgetbase.rb
Will generate this top level code:
if $0 == __FILE__
about = KDE::AboutData.new("knotifywidgetbase",
"KNotifyWidgetBase", "0.1")
KDE::CmdLineArgs.init(ARGV, about)
a = KDE::Application.new()
w = KNotifyWidgetBase.new
w.show
a.exec
end
Loading .ui files at runtime with Qt::UILoader
cleanup confusing sections and fix sections which contain a todo
Remove example that does not work
You can load a Qt Designer .ui file at runtime with the 'quiloader' extension, for example:
require 'Qt4' require 'quiloader' a = Qt::Application.new(ARGV) if ARGV.length == 0 exit end if ARGV.length == 2 QUI::WidgetFactory.loadImages ARGV[0] w = QUI::WidgetFactory.create ARGV[1] if w.nil? exit end w.show() a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()')) a.exec() end
With new version API changed a little.
require 'Qt4' require 'qtuitools' a = Qt::Application.new(ARGV) if ARGV.length == 0 exit end if ARGV.length == 1 file = Qt::File.new(ARGV[1]) file.open(Qt::File::ReadOnly) loader = Qt::UiLoader.new window = loader.load(file, nil) file.close
if (window.nil?) print "Error. Window is nil.\n" exit end window.show a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()')) a.exec end
API reference
Use the bin/rbqtapi tool to discover which methods are available in the QtRuby api. This command:
$ rbqtapi 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 qtrubyexamples and korundum/examples.
KDE Specific Infomation
Instead of require 'Qt4'
, userequire 'korundum4'
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.
Build dependencies
- ruby 1.8 or greater (svn trunk works with 1.9.1)
- cmake 2.6 or greater
- Qt 4.0 or greater
- KDE 4.1 or greater (for korundum)
Tutorials
There is a ruby translation of Qt Tutorial #1, and the corresponding ruby code is in qtruby/rubylib/tutorial/t1 to t14.
And a Qt4 version of the same tutorial translated to Ruby by Darshan Ishaya Qt4 Ruby Tutorial
Qt Tutorial #2, a Charting Application with ruby code in qtruby/rubylib/examples/qt-examples/chart.
The Qt Designer Color Tool Tutorial, with ruby code in qtruby/rubylib/designer/examples/colortool.
Paul Lutus has written a tutorial on how to get started with Ruby GUI programming with Qt
For KDE, there is a ruby translation of this KDE 3.0 tutorial originally written for C++ by Antonio Larrosa Jiménez. The sources are in korundum/rubylib/tutorials/p1 to p9.
The book Rapid GUI Development with QtRuby is now available.
There is also an approach to create an Ruby-Qt/KDE Book under a free license. The content will be created in this wiki. The book made with latex will be derived from the content in the wiki. Any Questions? Contact me!
Download
You can obtain recent SVN snapshots on the Rubyforge QtRuby/Korundum site.
More help
There are two IRC channels (#qtruby and #kde-ruby) in FreeNode. If you prefer e-mail, you can use the kde-bindings mailing-list (low traffic) or ask in the ruby-talk mailing list (you may use the Ruby Forum gateway to post in ruby-talk from web).
More information
A series of articles on ruby QT (inspired by the work done for the dradis project):