[Kde-bindings] Qt::Object.connect for ruby-blocks
Richard Dale
rdale at foton.es
Mon Sep 4 10:03:37 UTC 2006
On Saturday 02 September 2006 17:05, kelko wrote:
> Hi,
> In #kde-ruby there started a discussion of being able to pass a block
> directly to Qt::Object.connect so it is called everytime a signal is
> emitted. working on it and talking about it witch Richard i wrote code
> to add support for such calls to qtruby.
> Actually it has to be called another method to support block yet, but
> we want to get it working directly in the same method.
>
> When the file appended is required in a ruby-app you can do things like:
> Qt::Object.connect2Block(Qt::PushButton.new(), SIGNAL("clicked()")) do
> puts "Hello World"
> end
>
> In the block you can access other objects available in the context
> where the block was created.
>
> You can even work with signals having arguments:
>
> Qt::Object.connect2Block(KDE::HTMLPart.new().browserExtension,
> SIGNAL("openURLRequestedDelayed(const KURL&, const KParts::URLArgs&)")
> do | kurl, args|
> puts kurl.url
> end
>
> Both of the calls I checked and they are working.
>
> The way this new methods work is quite simple:
> it take the block passed and passes it to a new created "proxy" (an
> instance of Qt::BlockInvocator) altogether with the arguments of the
> signal. the BlockInvotator creates the slots "process" with the very
> arguments of the signal so it fits perfectly. Then the signal will be
> connect using the normal Qt::Object.connect to the slots "process" of
> the instance of BlockInvocator.
Yes, I like this idea and it will be very useful for QtRuby programming. I had
been thinking of adding a new slot with the name based on the address of the
block or something. But using a 'proxy' object to handle the block invocation
is better and simpler.
I'd like to change the other forms of connect() too so they can take blocks
too. Eg:
connect(a, SIGNAL(:siga), b, SLOT(:slotb)) could have one less argument and
take a block instead:
connect(a, SIGNAL(:siga), b) { ... }
I thought about how the BlockInvocator would work with garbage collection, and
I think we need to give it the target QObject in its constructor and that
would become the parent QObject. Otherwise there would be no references to
the BlockInvocator in Ruby and it could get gc'd. I think I prefer the
name 'Qt::Proc', but the user would never use it directly so it doesn't
matter too much.
Another issue is how to invoke the block - in you code you have:
@toCall.call(*vars)
So is that evaluated in the context you originally passed the block, and not
the context that the target of the slot now has? I'm not sure and would have
to experiment.
I wonder if it should be like this instead, especially for the example
connect() I give above:
parent.instance_eval(@toCall)
But then I don't see how you pass arguments to the block in that form.
-- Richard
More information about the Kde-bindings
mailing list