1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
Please see kdebindings/qtruby/README
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.
- DCOP Support. Here is a minimal ruby dcop slot implementation:
require 'Korundum'
class MyWidget < KDE::PushButton
k_dcop 'QPoint mySlot(int,QString)'
def initialize(parent, name)
super
end
def mySlot(counter,greeting)
return Qt::Point.new(50, 100)
end
end
This slot is passed an integer and a string, and returns a Qt::Point.
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.
- Define a dcop slot like this in one ruby program:
k_dcop 'QPoint getPoint(QString)'
def getPoint(msg)
puts "message: #{msg}"
return Qt::Point.new(50, 100)
end
- Call it from another program and print the reply, like this:
dcopRef = KDE::DCOPRef.new("dcopslot", "MyWidget")
There are three different ways to specify a DCOP call:
1) res = dcopRef.call("getPoint(QString)", "Hello from dcopsend")
2) res = dcopRef.call("getPoint", "Hello from dcopsend")
3) res = dcopRef.getPoint("Hello from dcopsend")
puts "result class: #{res.class.name} x: #{res.x} y: #{res.y}"
If the dcop slot has a 'void' or 'ASYNC' type, the result will be true
if the call succeeds or nil if it fails
- DCOP Attributes
You can set a dcop attribute like this, instead of calling
'klipper.setClipboardContents("Hello there klipper")':
klipper = DCOPRef.new("klipper", "klipper")
klipper.clipboardContents = "Hello there klipper"
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 camel case DCOP method name conversion
Any underscores in a method name are removed, and the following
character is capitalised. For example:
res = dcopRef.get_point("Hello from dcopsend")
Is a synonym for:
res = dcopRef.getPoint("Hello from dcopsend")
- Send to a DCOPRef:
There are two different ways to specify a DCOP send:
1) res = dcopRef.send("mySlot(QString)", "Hello from dcopsend")
2) res = dcopRef.send("mySlot", "Hello from dcopsend")
The result will either be true or false (but not nil for fail like the
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:
String => QString
Float => double
Integer => int
TrueClass|FalseClass (ie 'true' or 'false') => bool
Qt::Widget etc => QWidget
KDE::URL etc => KURL
Array => QStringList
Specify the full C++ type signature using the form
'dcopRef.call("getPoint(int,QString)", 5, "foobar")' if these rules fail
to pick the right method.
- DCOP Signals are defined like this:
k_dcop_signals 'void testEmitSignal(QString)'
def doit()
emit testEmitSignal("Hello DCOP Slot")
end
- Connect slot 'mySlot' to a DCOP signal like this:
res = slottest.connectDCOPSignal("dcopsignal", "SenderWidget",
"testEmitSignal(QString)", "mySlot(QString)",
true)
- Use the '-kde' option with the rbuic tool to require the 'Korundum'
extension rather than the 'Qt' one. If the '-x' option is used in
conjunction, it generates a KDE top level. For example:
$ rbuic -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
a.setMainWidget(w)
w.show
a.exec
end
|