[Kde-bindings] Qt::Object.connect for ruby-blocks

Richard Dale rdale at foton.es
Mon Sep 4 11:27:58 UTC 2006


On Monday 04 September 2006 12:05, kelko wrote:
> Richard Dale wrote:

> > 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) { ... }
>
> Why would you want to bind a block to a target? (the third argument)
> For if the block executes in the context of where it was created then I
> for myself don't see a need for such a thing.

Here we would expect the blocked to be called in the context of 'self':

connect(a, SIGNAL(:siga)) { ... }

But here, I would expect the block to be called in the context of 'b':

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.
>
> Good point about the garbage collector.
> What about registering the BlockInvocator as child of the source of
> the signal?
Because the block is being invoked in the context of the target, not the 
instance emitting the signal. Therefore it makes more sense to have the 
target (ie 'b' above) as the QObject parent of the block.

> Then there would be no need for a third argument for a connect-call.
> An other way would be to create a @@procs = [] containing all ever
> created BlockInvocators. But that ain't pretty.
Yes, I don't like that one either, and I think using the existing Object 
object tree is quite elegant.

> > I think I prefer the name 'Qt::Proc', but the user would never use
> > it directly so it doesn't matter too much.
>
> Yeah, that's why I haven't called it Qt::Proc for the proxy doesn't
> seem to fit the name "Proc" for it can't be used by developers inside
> the apps as Qt-Version of ruby-procs.
Ok, it needs more thought. I don't think 'Invocator' is a proper work - it 
should either be 'Invocation' or 'Invoke'  or 'Invoker' as far as I know. So 
Qt::InvokeBlock or Qt::BlockInvocation perhaps.

> > 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 tried at home such a call and it worked, but will try more today
> when i am back home:
> @button = KDE::PushButton.new(self)
> Qt::Object.connect2Block(@button, SIGNAL('clicked()')) {
>     @button.text = "Hi"
> }
>
> When i pressed the button the text of it changed.
Yes, I was thinking of the other case when there are three args, plus a block 
and it should be invoked in the context of the last arg.

@button = KDE::PushButton.new(self)

class Foo < Qt::Object
    def initialize
        super
        @button = KDE::PushButton.new(self)
   end
end

@other_button = Foo.new

Qt::Object.connect2Block(@button, SIGNAL('clicked()'), @other_button) {
    @button.text = "Hi"
}

Here I would expect it to set the text of the button in Foo class as the 
target connected to the signal is an instance of Foo.

-- Richard



More information about the Kde-bindings mailing list