[Kde-bindings] Qyoto: SIGNALS/SLOTS

Arno Rehn arno at arnorehn.de
Sun Feb 5 15:46:38 UTC 2006


Am Montag, 16. Januar 2006 21:31 schrieb Richard Dale:
> On Monday 16 January 2006 18:53, Arno Rehn wrote:
> > Hi,
> >
> > as I have absolutely no clue how to get signals and slots working with
> > QMetaObjects, I have another idea:
>
> Well, we just need to copy the QtRuby code for constructing them on the
> fly, but derive the signal and slot names via C# reflection. For signals,
> we look at the IQApplicationSignals interface or what ever, and for slots
> we go through the methods via reflection looking for which ones are marked
> with Q_SLOT. Then a Qyoto class which has been subclassed, would return a
> QMetaObject with those extra slots/signals from the QObject.MetaObject()
> method call. Then when there is a qt_invoke() virtual method callback, it
> would need to know if it was calling C# slots or C++ ones. If C#, then it
> does something similar to a virtual method callback. If C++ it just calls
> the qt_invoke() method in the superclass, which would in turn call a C++
> slot.

OK, but for this the wrapper for C++-instances to C# has to be finished, 
otherwise the QObject.MetaObject() call from C# won't have success.

> > With the unsafe keyword, the documentation says, we can code normal C in
> > C#, so I wondered if we could do something like Qt#'s libqtsharp (yeah, I
> > know again it's Qt#...), but dynamically and in the C#-code. Maybe it
> > would be possible do create something like a moc but for C#, which
> > creates code for each class containing the methods for connecting a
> > signal to a slot...
>
> It isn't any harder to do what I've described above, I'm sorry I haven't
> explained what needs doing very well.
>
> Here's what I've been doing this weekend, maybe have a look at this code? I
> haven't finished it, but maybe you can help. The reflection call needs to
> obtain this dummy constructor:
>
> 	[SmokeClass("QApplication")]
> 	public class QApplication : QObject, IDisposable {
>  		protected QApplication(Type dummy) : base((Type) null) {}
> 		interface IQApplicationProxy {
>
> So the code below works, but it will get any non-public constructor, rather
> than the one with the specific arg of 'Type dummy'. I couldn't work out how
> to use 'GetConstructor()' for protected constructors:

This should work:
ConstructorInfo constructorInfo = klass.GetConstructor(BindingFlags.NonPublic 
| BindingFlags.Instance, null, new Type[ ] { typeof( Type ) } , null);

I don't know where you need the BindingFlags.DeclaredOnly, I left it out and 
it still worked...

> 		// CreateInstance() creates a wrapper instance around a C++ instance
> which // has been created in C++ code, and not via a Qyoto C# constructor
> call. // It takes the class name string and obtains its Type. Then it finds
> the // dummy constructor which takes a Type as an arg, like this for
> example: //
>  		//		protected QWidget(Type dummy) : base((Type) null) {}
> 		//
> 		// The constructor is run to create the wrapper instance. Then the method
> 		// to create the transparent proxy to forward the method calls to
> 		// SmokeInvocation.Invoke() is called. In the case of the QWidget
> 		// example above, this method would be called 'CreateQWidgetProxy()'.
> 		static IntPtr CreateInstance(string className) {
> 			Type klass = Type.GetType(className);
>
> 			ConstructorInfo[] constructorInfo = klass.GetConstructors(
> BindingFlags.NonPublic
>
> 																	| BindingFlags.Instance
> 																	| BindingFlags.DeclaredOnly);
>
> 			Type[] constructorParamTypes = new Type[1];
> 			constructorParamTypes[0] = Type.GetType("System.Type");;
> //			ConstructorInfo constructor =
> klass.GetConstructor(constructorParamTypes);
> 			if (constructorInfo[0] == null) {
> 				Console.WriteLine("CreateInstance(\"{0}\") constructor method missing
> {1}", className, constructorParamTypes[0]);
> 				return (IntPtr) 0;
> 			}
> 			object result = constructorInfo[0].Invoke(new object []
> { constructorParamTypes[0] });
> 			Console.WriteLine("CreateInstance(\"{0}\") constructed {1}", className,
> result);
>
> 			Type[] paramTypes = new Type[0];
> 			MethodInfo proxyCreator = klass.GetMethod("CreateProxy",
> BindingFlags.NonPublic
>
> 																	| BindingFlags.Instance
> 																	| BindingFlags.DeclaredOnly);
>
> 			if (proxyCreator == null) {
> 				Console.WriteLine("CreateInstance() proxyCreator method missing");
> 				return (IntPtr) 0;
> 			}
> 			proxyCreator.Invoke(result, null);
> 			return (IntPtr) GCHandle.Alloc(result);
> 		}
>
> I'll check in what I have anyway. This will fix the problem of not being
> able to wrap C# instances around C++ instances that have been created
> within C++, rather than via ordinary qyoto C# constructors.
>
> -- Richard
> _______________________________________________
> Kde-bindings mailing list
> Kde-bindings at kde.org
> https://mail.kde.org/mailman/listinfo/kde-bindings

-- 
MfG
Arno Rehn
arno at arnorehn.de



More information about the Kde-bindings mailing list