[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