[Kde-bindings] Qyoto: SIGNALS/SLOTS

Richard Dale Richard_Dale at tipitina.demon.co.uk
Wed Feb 8 18:23:18 UTC 2006


On Sunday 05 February 2006 15:46, Arno Rehn wrote:
> 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.
Yes, you're right. The wrapper code is finished, although it doesn't get 
called in the version in the svn. It just needed the bit you've hopefully 
sorted out below with the correct reflection constructor look up method call. 
I haven't finished the runtime QMetaObject creation yet, but I'll check in 
what I have and explain what needs to be done.

This is the function that creates the QMetaObject, and the last line 
'set_obj_info("QMetaObject", o)' is where it creates a C# wrapper instance:

static void *
make_metaObject(char * className, QMetaObject* parent, QMetaData * slot_tbl, 
int slot_count, QMetaData * signal_tbl, int signal_count)
{
	QMetaObject *meta = QMetaObject::new_metaobject(
	className, parent,
	(const QMetaData*)slot_tbl, slot_count,	// slots
	(const QMetaData*)signal_tbl, signal_count,	// signals
	0, 0,	// properties
	0, 0,	// enums
	0, 0);

    smokeqyoto_object * o = (smokeqyoto_object *) 
malloc(sizeof(smokeqyoto_object));
    o->smoke = qt_Smoke;
    o->classId = qt_Smoke->idClass("QMetaObject");
    o->ptr = meta;
    o->allocated = true;

	return set_obj_info("QMetaObject", o);
}

> > > 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...
OK, thanks that looks good I'll add it..

-- Richard



More information about the Kde-bindings mailing list