Below is a Qyoto/Kimono C# bindings 'Hello World' program written by Arno Rehn. Arno has done some quick performance measurements and he says Qyoto runs faster than a QtJava app running using IKVM, which is encouraging. I wasn't sure whether or not the method calls going via transparent proxies would be too slow, but there are major advantages in not needing C bindings using P/Invoke for each method call.
using System;
using Qt;
class MainForm : QDialog
{
static void Main(String[] args) {
QApplication qa = new QApplication(args);
MainForm mf = new MainForm();
mf.Show();
qa.SetMainWidget(mf);
qa.Exec();
}
public MainForm() : base()
{
this.Show();
QVBoxLayout qgrid = new QVBoxLayout(this);
qgrid.SetAutoAdd(true);
QTextEdit te = new QTextEdit(this);
te.Show();
QPushButton button = new QPushButton("Hello World! Are you getting warmer?", this);
button.Show();
}
}The next step is to design how slots and signals should work. This is what we're currently trying out; each slot is marked with a 'Q_SLOT' custom attribute, and the attribute data can be accessed via reflection and used to build a suitable QMetaObject on the fly for each QObject based class.
[Q_SLOT("void mySlot(QString)")]
public void mySlot(string arg)
{
...
}Signals are a bit trickier, as it would be nice to have them looking like delegates that you call. I'm not sure yet whether this can be done, so at first I think signals will be defined and used in a more 'Qt-like' manner. Here is an example of how the signals emitted by QApplication might look:
public interface IQObjectSignals {
[Q_SIGNAL("void Destroyed()")]
void Destroyed();
...
}
public interface IQApplicationSignals : IQObjectSignals {
[Q_SIGNAL("void LastWindowClosed()")]
void LastWindowClosed();
...
}
((IQApplicationSignals) myInstance.Emit()).LastWindowClosed();QObject.Emit() will return a transparent proxy constructed with the IQApplicationSignals interface above. The signal 'LastWindowClosed()' is emitted by invoking the method on the proxy. The method call can then be forwarded to an instance of 'SignalInvocation.Invoke()' where the C# arguments are marshalled to C++ ones and qt_emit() for Qt3 or QMetaObject::activate() for Qt4 will emit the signal via the Qt runtime.
The next important milestone will be a KDE hello world with slots/signals and virtual method overrides all working - that should take another week or two - maybe sometime in the new year I hope..

Capitalization
C# is a great language, but why did you choose to adopt the .NET style Pascal case for class members? The only reason that .NET used Pascal case was to be compatible with traditional Visual Basic coding style. But of course this is not .NET, and you are not supporting Visual Basic. In my opinion, camel case would have been a better choice. It requires less "shift" keys to be pressed and looks nicer when lowercase variable names are used. Also, using Pascal case for classes and camel case for variables allows you to distinguish the two
Re: Capitalization
I agree that .NET style Pascal method names are pretty ugly, but all the other bindings like GTK# or the former Qt binding Qt#, use it. And you're right that is does cause some problems with method names and enum names clashing in Qt - I've resolved that by making the method name start with a lower case letter if there is a clash with an enum. It would be nice to be able to use as many CLR languages as possible via the Qt binding (even Basic). The C# code is autogenerated and so it wouldn't be too difficult to change the case of the generated method names, if lower case was more popular with Qyoto users.
Just an idea
about the possible implementation of signals (that i had while i was studing the C# language
):
C# supports "events", defined with the keyword "event", that incapsulate delegates and, a bit like properties that have get/set sub-methods, they have add/remove sub-methods, that should likely register/unregister a delegate. This allows to write:
MyClass.OnMouseMove += MyHandler;
and i think that incapsulating signals in events (maybe with an attribute to specify the Qt-name) would be absolutely great.
Just my 2 cents.
How is it proceeding?
Hi,

at last i have seriously decided to learn C# and within the things i most care about now there are, of course, Qt/Kde bindings for C#
What's the current status of Qyoto/Kimono?
I'm asking because there has been no news about it lately (not even in the kde-bindings ml).
I'd be extremely happy to help with development but i think that i still need a bit of time to refine my C# knowledge before i'll be able to contribute
Thanks!
Re: How is it proceeding?
I'm afraid I've been too busy with the ruby bindings, kdevelop and my day job recently, and just haven't had any time. Which is really frustrating as Qyoto is quite close to being useful with just a bit more work. However, I don't think it's worth working on the qt3 version anymore, and so I'll concentrate on the qt4 one and at least that should be ready in time for KDE 4.
Any help would be really welcome if you have time. Maybe improving the way it builds would be a good place to start once you get up to speed with C#. It should build a Qyoto.dll and link against that, rather the recompiling everything as it does now.
crash with SetGeometry
Hi Richard,
thanks for these long-time-wanted Qt C# bindings!
I tried to use Qt in a sample C# application.
- I adapted your makefile to get libqyoto.so compiled and "referenced" it through ldconfig
- I created my own qt.dll by compiling everything in the kimono/qt3qyoto folder + SmokeInvocation.cs
(mcs -t:library -out:qt.dll -unsafe ../SmokeInvocation.cs -recurse:*.cs )
- I referenced my obtained qt.dll when compiling my sample code.
Compilation works fine.
However I have a problem, the method "SetGeometry(int, int, int, int)" doesn't work and makes my app crash:
Invoke() MethodName: Width Type: Qt.QWidget, qt3, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null ArgCount: 0
FindMethod() className: QMainWindow MethodName: width
In FindMethodId QMainWindow::width => 12483
FindMethod() MethodName: width result: 12961
FindMethod() single match 12961
In CallMethod methodId: 12961 target: 0x00000053 items: 0
In CallMethod 151988288
o->ptr: 0x93134d8 o->classId: 197
In callMethod() fn: 0x23bea48 method().method: 40 ptr: 0x93134d8 _stack[1]: 539784293
In callMethod() _stack[0]: 0x280
In MethodReturnValue(), type: int _stack[0] 0x280
In MethodReturnValue(), about to call return value marshaller
returned from CallMethod
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
in (wrapper remoting-invoke) Qt.QWidget:Width ()
in (wrapper remoting-invoke-with-check) Qt.QWidget:Width ()
in <0x00016> Qt.QWidget:Width ()
in [0x00072] (at /home/mb/Projects/test4/Main.cs:65) QtSamples.ScribbleWindow:.ctor ()
in (wrapper remoting-invoke-with-check) QtSamples.ScribbleWindow:.ctor ()
in [0x00007] (at /home/mb/Projects/test4/Main.cs:24) QtSamples.ScribbleWindow:Main (System.String[] args)
The crash occurs with every class I use :
QScrollView.SetGeometry, QFrame.SetGeometry ...
Is this normal for the moment? I got Kimono sources by checking svn yesterday. Some very simple apps (hello world) work fine.
Thanks!
Matt
Re: crash with SetGeometry
Hi Matt
I tried setGeometry(), and it worked fine for me. I've just implemented return types for primitive types, and your error above looks like something to do with a null return type. So if you try the current svn version it might work for you. If you have more trouble maybe try the kde-bindings@kde.org mailing list where we discuss the Qyoto/Kimono bindings.
Is this normal for the moment? I got Kimono sources by checking svn yesterday. Some very simple apps (hello world) work fine.
Yes, I'm afraid the project is still at a bit of an early stage, but going well. Slots and signals are probably the next thing to get working, after return types.
Great!
Even if the old Qt# project is dead, Qyoto looks very promising, and thanks to all those who have been working on it!
I'm now seriously thinking about writing my new Qt program(s) in C#
Re: Great!
Thanks. Qyoto/Kimono is fun to work on - C# is certainly an interesting systems programming language.
Go on!!!
Yes!!! This is a great project!
Please go on with it... it's so cool!!!!
Luca Ferrari
FoX Linux Founder
www.foxlinux.org