Skip navigation.
KDE Developer's Journals

Qyoto "hello world" working

richard dale's picture

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..

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
luckysandal's picture

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 Eye-wink

richard dale's picture

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.

ratta's picture

Just an idea

about the possible implementation of signals (that i had while i was studing the C# language Smiling ):
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.

ratta's picture

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# Smiling
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 Smiling
Thanks!

richard dale's picture

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.

_matt_'s picture

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

richard dale's picture

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.

ratta's picture

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# Smiling

richard dale's picture

Re: Great!

Thanks. Qyoto/Kimono is fun to work on - C# is certainly an interesting systems programming language.

luka4e's picture

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.