[Kde-bindings] Qyoto: SIGNALS/SLOTS
Richard Dale
Richard_Dale at tipitina.demon.co.uk
Mon Dec 12 17:01:07 UTC 2005
On Sunday 11 December 2005 14:39, Arno Rehn wrote:
> > I got this wrong, it should look like this:
> >
> > ((IQApplicationSignals) myInstance.Emit()).LastWindowClosed();
> >
> > And the interface for a class would need to extend the signals interface
> > for its superclass. So in the case above the IQApplicationSignals
> > interface would need to extend the IQObjectSignals interface. But this
> > doesn't really fit in with delegates.
> >
> > > > And it would be forwarded to SignalInvocation.Invoke(), in a similar
> > > > manner to how ordinary method calls get diverted to
> > > > SmokeInvocation.Invoke() at the moment.
>
> We don't need a thing like SignalInvocation if all the signal are
> delegates. With QObject.Emit() we would just call an delegate. I wouldn't
> use interaces at all, just delegates which are declared in the class
> directly. The delegates would be inherited by derived classes, too.
I think we might need two ways of emitting signals; one which looked as Qt/C++
like as possible, and the other which looks as C#/delegate like as possible.
I'm not sure if it's actually possible to do it with delegates though. The
QObject.Emit() syntax above can definately be made to work though.
> > > > But slots are easiest to get working first though, and marking them
> > > > with attributes like you've done looks pretty good to me.
> >
> > I think the slots need to be marked as slots, along with the C++ type
> > signature that would be used for constructing the QMetaObject entry for
> > it. Like this:
...
> Looks very good, but my question: How do we connect a native Qt-signal to a
> C#-method ? Can we trap these signals and then call a C#-method? Or can we
> connect a C++ signal to a C#-method directly?
We can trap signal calls by overriding the QObject::qt_invoke() method.
Below is my latest experiment with adding attributes to methods in interfaces
(which works). But I haven't worked out how to get a parent interface via
reflection yet (eg get IQObjectSignals from IQApplicationSignals - I'm sure
it's obvious, I just haven't spotted anything yet.
-- Richard
using System;
using System.Reflection;
public interface IQObjectSignals {
[Q_SIGNAL("void Destroyed()")]
void Destroyed();
// void Destroyed(QObject arg1);
}
public interface IQApplicationSignals : IQObjectSignals {
[Q_SIGNAL("void LastWindowClosed()")]
void LastWindowClosed();
void AboutToQuit();
void GuiThreadAwake();
}
[AttributeUsage( AttributeTargets.Method )]
class Q_SIGNAL : Attribute
{
public string signature;
public string Signature
{
get
{
return signature;
}
}
public Q_SIGNAL(string signature)
{
this.signature = signature;
}
}
public class main : Object
{
public static void Main(string[] args)
{
new main();
}
public main()
{
object[] attributes;
MethodInfo miSignal =
typeof(IQApplicationSignals).GetMethod("LastWindowClosed");
attributes = miSignal.GetCustomAttributes(typeof(Q_SIGNAL), false);
if (attributes.Length > 0) {
Q_SIGNAL signalAttr = (Q_SIGNAL) attributes[0];
Console.WriteLine( "Q_SIGNAL signature: {0}", signalAttr.Signature );
}
MethodInfo[] methods = typeof(IQApplicationSignals).GetMethods();
foreach (MethodInfo m in methods) {
Console.WriteLine( "method: {0}", m.Name );
}
// Which reflection method can be used to get the parent interface
// of IQApplicationSignals, so it doesn't need to be hard coded
// as IQObjectSignals like here?
miSignal = typeof(IQObjectSignals).GetMethod("Destroyed");
attributes = miSignal.GetCustomAttributes(typeof(Q_SIGNAL), false);
if (attributes.Length > 0) {
Q_SIGNAL signalAttr = (Q_SIGNAL) attributes[0];
Console.WriteLine( "Q_SIGNAL signature: {0}", signalAttr.Signature );
}
}
More information about the Kde-bindings
mailing list