Skip to content

Writing Qt and KDE apps in Mono Visual Basic

Tuesday, 23 September 2008  |  richard dale

I just wiped a partition on my laptop that had Mac OS X Tiger on it - I haven't used Mac OS X for a while and the disk space was just being wasted. I've replaced it with KDE from the Kubuntu Hardy disk I got at Akademy, and upgraded it all to 4.1. It was great to just start from scratch and only put in the latest things that I was interested in. One of the shiny new toys was Mono 1.9.1, along with some of the associated sub-projects such as the Visual Basic compiler.

I tried the Basic with the Qyoto C# bindings for a Qt hello world first. It took a bit of searching around in the sample VB source to grok the syntax and get it going. Here it is in its glorious, err 'Dim'ness (love the name of that keyword!):

Imports System
Imports Qyoto

Public Class TestSlot
    Inherits QObject

    ' Define a custom slot using a 'Q_SLOT' Attribute
    <Q_SLOT()> Sub Greet
        System.Console.WriteLine("Hello World Clicked")
    End Sub

    Shared Sub Main(ByVal args() As String)
        Dim app As QApplication = New QApplication(args)

        ' Connecting to a custom slot
        Dim hello As QPushButton = New QPushButton("Hello world!")
        Dim test As TestSlot = New TestSlot()
        Connect(hello, SIGNAL("clicked()"), test, SLOT("Greet()"))

        ' Setting a property
        hello.ObjectName = "My Button"

        Dim label As QLabel = New QLabel(hello)
        hello.Resize(100, 30)     
        hello.Show()
        QApplication.Exec()
    End Sub
End Class

I think it's pretty much self explanatory. The code subclasses QObject and defines a custom slot connected to a button click via slots and signals. In Qyoto C# you define a custom slot like Greet() above like this:

    // Define a custom slot using a 'Q_SLOT' Attribute
    [Q_SLOT()] 
    void Greet() {
        System.Console.WriteLine("Hello World Clicked");
    }

In Basic, the Q_SLOT() Attribute goes inside angle brackets on the same line as the name of the slot method. If you want to put it on the line before, like C#, you need to add an underscore after it. I'm not really a Basic expert, but I had thought you didn't need to define the types of variables. I expected that you could write:

        Dim label = New QLabel(hello)

But that doesn't seem to work and maybe I had been imagining that there was some kind of compiler flag to enable more dynamic behaviour.

Next I tried a KDE Kimono app, and hello world came out looking like this:

Imports System
Imports Qyoto
Imports Kimono

Public Class P2
    Shared Sub Main(ByVal args() As String)
        Dim about As KAboutData = New KAboutData(   New QByteArray("p2"), 
                                                    New QByteArray("Hello World"), 
                                                    KDE.Ki18n(""), 
                                                    New QByteArray("0.1") )
        KCmdLineArgs.Init(args, about)
        Dim app As KApplication = New KApplication()
        Dim hello As QPushButton = New QPushButton(KDE.I18n("Hello World !"), Nothing)

        app.SetTopWidget(hello)
        hello.Show()

        KApplication.Exec()
    End Sub
End Class

One little problem I had was that the implicit constructor to convert strings to QByteArrays wasn't working, and I needed to explicitely create the QByteArrays. In C# there is a nice feature where you can define these sort of conversions, and the QByteArray one looks like this:

namespace Qyoto {
    using System;
    public partial class QByteArray : Object, IDisposable {
        public static implicit operator QByteArray(string arg) {
            return new QByteArray(arg);
        }
    }
}

This should mean that everywhere in the Qt or KDE apis where a QByteArray is expected, you can just pass a string and it will get converted. C++ does the same thing with implicit constructors, which are on by default and you have to turn off the behaviour by making them 'explicit'. I think I prefer the C# way as it makes it clearer what is going on to me. So for some reason the implicit constructors weren't being called in Visual Basic, which might be a bug or maybe there is some syntax of compile flag I don't know about to enable it.

So there we have it - another language you can write KDE apps in (and Plasma applets too of course). Maybe it will allow less experienced programmers who are frightened of C++/C#/Ruby etc, to get going. What we really need is a nice dead simple IDE like Gambas to go with it though. I been reading Miguel de Icaza's blogs aobut C# Interactive Shell/Embeddable compiler, and it would be really nice to have something like that for VB too to build into an IDE.