Skip to content

Random programming languages with Qt4 and QtJambi

Saturday, 12 May 2007  |  simon edwards

In between porting some of my older KDE 3 C++ over to Python and Qt/KDE 4, and also fixing some bugs in Guidance, I've had a little play around with QtJambi. QtJambi is Trolltech's new bindings generator and bindings for using Qt4 on Java. Or to be more accurate I should say that the bindings are for the Java Virtual Machine, and not just for programs written in the Java language. One of the interesting features about VMs is that they don't have to be tied to a single programming language. You can run all sorts of different languages on the Java VM or the .NET / Mono VM. Now, one of the not just interesting, but really /cool/ features of VMs is you usually don't need huge slabs of binding code if you want one language to call code written in another, provide both languages are running on the VM itself. To put it simply: you can use QtJambi with a whole swag of different languages that run on the Java VM. Here is a little example of the Qt analog clock example written some other weird and wacky language: (anyone know which?)

package com.trolltech.examples

import com.trolltech.qt.core._
import com.trolltech.qt.gui._

class AnalogClock(parent: QWidget) extends QWidget(parent) {

    def this() = {this(null) }
 
    var hourHand = new QPolygon
    var minuteHand = new QPolygon
 
    hourHand.append(new QPoint(7, 8 ))
    hourHand.append(new QPoint(-7, 8 ))
    hourHand.append(new QPoint(0, -40))
 
    minuteHand.append(new QPoint(7, 8 ))
    minuteHand.append(new QPoint(-7, 8 ))
    minuteHand.append(new QPoint(0, -70))
 
    var m_timer = new QTimer(this)
    m_timer.timeout.connect(this, "update()")
 
    setWindowTitle("Analog clock")
    setWindowIcon(new QIcon("classpath:com/trolltech/examples/qt-logo.png"))
    resize(200, 200)
 
    override protected def paintEvent(e: QPaintEvent) = {
        var hourColor = new QColor(127, 0, 127)
        var minuteColor = new QColor(0, 127, 127, 191)
 
        var side = if (width < height) width else height
 
        var time = QTime.currentTime

        var painter = new QPainter(this)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        painter.translate(width / 2, height / 2)
        painter.scale(side / 200.0f, side / 200.0f)

        painter.setPen(QPen.NoPen)
        painter.setBrush(hourColor)

        painter.save
        painter.rotate(30.0f * ((time.hour + time.minute / 60.0f)))
        painter.drawConvexPolygon(hourHand)
        painter.restore

        painter.setPen(hourColor)

        for (val i <- 1 to 12) {
            painter.drawLine(88, 0, 96, 0)
            painter.rotate(30.0f)
        }

        painter.setPen(QPen.NoPen)
        painter.setBrush(minuteColor)

        painter.save
        painter.rotate(6.0f * (time.minute + time.second / 60.0f))
        painter.drawConvexPolygon(minuteHand)
        painter.restore

        painter.setPen(minuteColor)

        for (val j <- 0 to 60) {
            if ((j % 5) != 0) {
                painter.drawLine(92, 0, 96, 0)
            }
            painter.rotate(6.0f)
        }
    }

    override def sizeHint() = new QSize(200, 200)
    override def showEvent(e: QShowEvent) = m_timer.start(1000)
    override def hideEvent(e: QHideEvent) = m_timer.stop
}

object AnalogClockMain {
    def main( args: Array[String] ): unit = {
        QApplication.initialize(args)
        var w = new AnalogClock
        w.show
        QApplication.exec
    }
}

This is in Qt4 programming in Scala (http://www.scala-lang.org/), a staticly typed language which uses type inference and mixes object oriented programming with functional programming. It is quite interesting to play with. At first glance it is kind of like Java with a lot of the mind-numbing redundancy removed; a lot of the benefits of static typing without the high cost.

I should have another go with Jython, last time I got as far as hooking up some signals before hit snags. I'm curious to know how it stacks up with CPython + PyQt.