[Kde-bindings] disconnecting a block in qtruby4

Richard Dale rdale at foton.es
Tue Jan 13 20:08:28 UTC 2009


On Thursday 08 January 2009 10:07:23 Stefano Crocco wrote:
> In qtruby4, you can connect a signal to a block, but is there a way to
> disconnect the signal afterwards? One way, of course would be to use
> disconnect passing only the name of the signal, but that would disconnect
> all slots/block/signals connected to it. For example:
>
> btn1 = Qt::PushButton.new
> btn2 = Qt::PushButton.new
> btn1.connect(SIGNAL('clicked()')){puts "btn1 clicked"}
> Qt::Object.connect btn1, SIGNAL('clicked()'), btn2, SIGNAL('clicked()')
>
> If I then do:
>
> btn1.disconnect SIGNAL('clicked()')
>
> which, as far as I know, it's the only way to disconnect the block from the
> clicked() signal of btn1, I would also disconnect the clicked() signal of
> btn2, which may not be what I want.
>
> Is there another way to do this? The reason I'm asking this is that I'm in
> a situation like the one in the following piece of code:
>
> require 'Qt4'
>
> app = Qt::Application.new []
> b1 = Qt::PushButton.new('Change label')
> b2 = Qt::PushButton.new('Delete label')
> l = Qt::Label.new 'Test'
> b1.connect(SIGNAL('clicked()')){l.text = "TEST"}
> b1.show
> b2.connect(SIGNAL('clicked()')){l.dispose}
> b2.show
> l.show
> app.exec
>
> Here there are two push buttons and one label. One button changes the text
> of the label; the other disposes of the label. If I press the second
> button, then the first, I get a crash, because the label doesn't exist
> anymore, but the block which changes its text is still called and there's
> no way to disconnect it (of course, the real situation is much more
> complex, so simple solutions which would work here, such as calling
> b1.disconnect( SIGNAL('clicked()')) from the block connected to b2 wouldn't
> be availlable to me).
The trouble is that the whole point of blocks is that they are anonymous.

> Looking at the code for Qt::Internal.signal_connect, which (according to
> the comments) should manage the connections with blocks, this kind of
> connections actually connect an internal Qt::SignalBlockInvocation object
> to the signal and that object, I guess, calls the signal in one of its
> slots. If the connect method returned the Qt::SignalBlockInvocation object,
> it could be used as argument to disconnect to break the connection. Could
> it be done? Or is there another way to do what I'm asking?
I would rather connect() stayed returning a boolean I think. 

The new Qt::SignalBlockInvocation will be a child of the thing you connected 
it to, and so you can use thing.children obtain it and pass it to a disconnect 
call perhaps. I can't think of a syntax for doing that which would look tidy 
enough to be added to QtRuby at the moment though.

>
> On a related subject, is there a reason for which there's a
> Qt::Object.connect class method (corresponding to the static C++ method),
> but not a corresponding Qt::Object.disconnect class method?
It works for me:

class Foo < Qt::Object
  slots :my_slot
  def my_slot
    puts "In my_slot"
  end
end

app = Qt::Application.new(ARGV)
b = Qt::PushButton.new('hello')
foo = Foo.new

Qt::Object.connect(b, SIGNAL(:clicked), foo, SLOT(:my_slot))
Qt::Object.disconnect(b, SIGNAL(:clicked), foo, SLOT(:my_slot))
b.show
app.exec

If you comment out the disconnect the slot gets called.

-- Richard



More information about the Kde-bindings mailing list