gunnar
Uncategorized
Qt
Qt Jambi
WebKit
Qt Concurrent
Graphics View
Patternist
Posted by gunnar
 in Uncategorized, Qt, Qt Jambi, WebKit, Qt Concurrent, Graphics View, Patternist
 on Tuesday, June 10, 2008 @ 09:13

So the time is finally here. Qt 4.4.0 was released a few weeks ago and as promised Qt Jambi is right behind. A lot of effort has gone into this one, in addition to supporting all the new Qt features, like Phonon, Webkit, Widgets in Graphics View, XQuery and Qt Concurrent, we also have a seriously improved deployment system, JDBC support and a compile-time checked signal-slot approach for the paranoid. Its a good time to be a Java developer I tell yah! We already mentioned all the featuers in the Qt Jambi 4.4.0 Preview Blog so we won’t repeat ourselves here… (There is a danger in linking to eskils blog, as it links to others again, which again links to others, which in the end proves to be a fairly complex graph, but then again… we are engineers and like that kind of stuff)

Under the cover we’ve also done quite some work. We also did an overhaul of the garbage collection and memory management subsystem and hopefully ironed out all the bumps and dents. We’ve also done some work on the build system, so that our users that build from source have a bit more substantial buildsystem to work with. Previously it was a complex install document, which has been replaced by a simple ant command which just does it all… I was very happy to see that the deployment system & ANT build scripts works well enough for the webstart to look like a plain, normal webstart app:

<resources>
<j2se version="1.5+"/>
<jar href="qtjambi-examples-4.4.0_01.jar"/>
<jar href="qtjambi-4.4.0_01.jar"/>
</resources>

<resources os="Windows" arch="x86">
<j2se version="1.5+"/>
<jar href="qtjambi-win32-msvc2005-4.4.0_01.jar"/>
</resources>

No magic nativejar or anything like that, just the qtjambi-win32-msvc2005-4.4.0_01.jar in the classpath and that is enough to load it, jpeg and svg plugins and all. The good thing is that the files included in the webstart are produced directly by the ant script with all dependencies etc set up properly… (well… almost properly, it took us an evening last week to get it really working, but now it works properly). Because of the fixes to memory management and deployment Eskil and I got these offical diplomas:

Absolutely last load issue fixed and Last memory managment bug

So, what more is there to say… Try the webstart with its new demos, download the packages and start hacking!

-
The Qt Jambi Team

gunnar
Qt
Qt Jambi
Posted by gunnar
 in Qt, Qt Jambi
 on Tuesday, February 05, 2008 @ 08:39

I planned on writing a blog about some of the work we’ve done on deployment for Qt Jambi 4.4, but I realized when writing that the memory of “Why the !”#!%!§ doesn’t it work on that linux box!” was still to fresh in memory and I was simply to upset to write anything about it. Some time has passed and a Finnish company came along, putting things into perspective, so now I can calmly share some thoughts on deployment with you…

Deploying C++ software across multiple platforms can be rather painful, partially because Qt doesn’t really provide any tools to help out. We do provide deployment guides for the various systems, but our users still have to learn and understand all the details. It doesn’t “just work”. Why? you may ask…

On windows life used to be pretty simple, you ship your .exe and .dll’s together in the same directory together with the right runtime libraries and you’re set, alternatively build with Visual Studio 6.0 and almost don’t worry about it at all. This was until a certain company introduced manifests as a way of describing dependencies between libraries and executables. It does sound great on paper, but in practice it really doesn’t work, especially if the executable (java.exe in this case) is built without manifest. As a direct effect, you are now required to either preinstall the runtime libraries in the WinSxS folder (via installer) or duplicate the runtime libraries in all directories that contain executable code, such as /lib, /bin and /plugins/…, meaning that each plugin directory needs to have its own duplicate copy of the MS runtime libraries. Should you choose to not follow these rules, the application won’t run…

On Linux we have the problem that the various systems are vastly different. Some boxes didn’t have Xinerama installed, some have libstdc++ version 5, some have version 6. Some have Qt installed with debug symbols and some have Qt 3 installed. Basically there are a lot of variables and the only way to go about this is for our users to ship a complete bundle containing all dependencies. In Qt 4.4 we changed Qt in some places to support dynamic resolving and loading a few X libs which reduced the dependency table a bit. In Qt 4.3 our binaries were built without Xinerama for instance, to make them run on certain systems. Since Qt 4.4 we support Xinerama if its available on the deployment machine out of the box.

On Mac OS X, things are immediately rather bright, save for this minor issue of install_name… Install names describes, among other things, the location of dependent binaries. When build Qt libraries in the default way, the dependencies will be absolute file names to things like ~/qt/lib/libQtCore which doesn’t work on a target machine. In Qt 4.3, we patched our prebuilt binaries to contain relative paths to where they were loaded from, but our users who built Qt Jambi themselves would have to do this too, which is a rather messy process. Why not simply use frameworks or bundles, and the reason is simply that we want to have a means of deployment that feels java-like and works identically across all platforms, so our users can understand this, and not care anymore about deployment on any target system. Frameworks and bundles are pretty far from that…

In addition to these platform spesific problems, we have the issue that in Java, you normally relate to .jar files which are portable while native libraries, such as the Qt C++ libraries, have to be available on the file system for the application to load them. These native libraries need to be available through the java.library.path, which equals the environment variables PATH on windows, LD_LIBRARY_PATH on Linux / UNIX and DYLD_LIBRARY_PATH on OS X. In Qt Jambi 4.3 we did provide some magic to automatically find the libraries without the environment variables, but ideally you want to relate to just .jar files, right? Well… With Qt Jambi 4.4 you can!

What we ended up doing is that we created some ant tasks to help us and our users out. The way it works is that we have build tasks for running qmake, make and juic and a task for bundling. The bundle task will make sure the binaries have the right install name in place on Mac OS X and on windows it will copy the manifests and runtimes into the right subdirectories. The result of this is a .jar file, for instance qtjambi-win64-msvc2005-4.4.0_01.jar which contains the correct native binaries for Windows 64bit and when its in the classpath, it will just work. Similarly it will create a qtjambi-linux32-gcc-4.4.0_01.jar for linux, and if you put both the two in the classpath, it will pick the right one.

This makes it extremly easy for the people that deploy a plain Qt Jambi application, as they simply include a .jar file in their classpath and it works. The slightly more complex scenario is where you generate some code using the Qt Jambi Generator and want to deploy that. The process is rather similar, you simply add your binaries to the bundle task and you get a .jar file containing Qt Jambi native libraries and you own native libraries and once again you are set. We still support loading binaries from the environment variables listed above, which is handy for development and for starting Qt Jambi from a C++ app, like Qt Designer, so hopefully, we covered most scenarios.

We hope to have the Qt Jambi 4.4.0_01 Beta out by the end of february, so I’m looking forward to getting your feedback on this…

gunnar
Qt
KDE
Qt Jambi
Posted by gunnar
 in Qt, KDE, Qt Jambi
 on Tuesday, November 06, 2007 @ 09:05

Some time ago a question popped up on qt-jambi-interest about how Qt Jambi would work together with jython. The main problem was signals and slots as our string-based approach doesn’t map to well into the world of interpreted languages on top of Java. I sat down some time ago and got jython to work pretty smoothly and the code has been sitting on my disk for a while, but I finally got around to making a project out of it. Below you see a small painting application I created.

The code for the signal / slot binding is available here:
http://labs.trolltech.com/page/Projects/QtJambi/jython

Happy coding!

jython_drawing

gunnar
Qt Jambi
Posted by gunnar
 in Qt Jambi
 on Friday, September 28, 2007 @ 08:12

A few weeks back Eskil and I traveled to JavaZone, the biggest Java conference in Scandinavia, and Trolltech had a booth there and I did a presentation. We also got to meet several of our Qt Jambi users. Its always cool to see and hear what people are doing with the tools your developing and there are some pretty cool Qt Jambi things happening out there ;-)

Anyway.. One thing that came up when talking to people was that our signal / slots connections seem dangerous. So when it comes to the piece of code that looks like this:

ui.lineEdit.textChanged.connect(this, "setText(String)");

one sees the String and thinks that, if there is a typo there, my app is busted. Well… it would be if that piece of code wasn’t tested. Luckily most signal/slot connections are set up during object initialization, so that a typo here would be detected as you develop your class. Most development is done in a cycle of “develop and test and again”, so in practice this is mostly not a problem. And of course, we all know that developers never write errors in strings anyway, right? ;-)

Another problem that one will find with the current string approach is that it doesn’t give live feedback and syntax completion in IDE’s like Eclipse or IntelliJ. (Interestingly enough, it does in emacs, because my emacs completion is based on recently parsed strings instead of the actual code, which means it always completes something, though with a 5% error-ratio). So you have two problems with the current approach, first that Strings don’t feel save (even though they mostly are) and that they don’t give you live feedback. Internally we came up with an alternative quite some time ago and have been mentioning it to people who have asked, but I think its time to publish it.

The idea was to introduce a class QSignalHandlerX which offers complete compile-time type checking and offering better support for live feedback in IDE’s. The QSignalHandlerX class should have an abstract method that you had to reimplement, which did take correct types as parameter. Based on this you could create anonymous inner classes on the fly whenever you need to handle a signal and reimplement the method to handle the signal. Instead of the string connection you get:

new QSignalHandler1<String>(ui.lineEdit.textChanged) {
    public void handle(String s) {
        System.out.println("Got the string: " + s);
    }
}

In this case we use generics to match the types of the signal with the type of the signal handler. If the two have different signature you get a compile error and if you forget to add the String generics argument to the QSignalHandler you’ll get a warning telling you its “unsafe” or something similar. The 1 at the end of the QSignalHandler is the number of arguments, similar to the one in QSignalEmitter.Signal. This is already in our 4.4 branch, but the code is trivial so if you want this right away, I’ll give you a sample that you can “steal” and use.

package com.trolltech.extensions.signalhandler;

import com.trolltech.qt.*;

/**
 * Signal handlers are a convenience class that provides compile time type checking of signal / slot
 * connections.
 */
public abstract class QSignalHandler1<T> {

    /**
     * Creates a new signal handler that sets up a connection from the input signal to this object.
     * @param signal The signal to connect to.
     */
    public QSignalHandler1(QSignalEmitter.Signal1<T> signal) {
        signal.connect(this, "handle(Object)");
    }

    /**
     * Reimplement this function to handle responses to the signal this handler is connected to..
     * @param arg The Signal argument
     */
    public abstract void handle(T arg);
}

So as you can see, it is pretty straightforward. We move the string into the QSignalHandler class so that it is then checked, tested and verified once and for all and then all future use of QSignalHandler is checked. Because of the recurring generics type T we guarantee that the user uses the same type throughout the signal handler and its anonymous subclass.

If you have feedback on this API, please let us know…

gunnar
Qt Jambi
Posted by gunnar
 in Qt Jambi
 on Friday, August 31, 2007 @ 16:09

Qt Jambi has been out for some weeks now and up until now there wasn’t a really good option for doing Database programming there. As an opensource developer you could go ahead and download the Qt source packages and build the database drivers from scratch, and the commercial owners that were curious got a special sourcepackage that let one build the database drivers from scratch. Now, this is all very painful, so one might be asking, why didn’t we provide binaries for those drivers in the first place…

Well… Its mostly because the C-API’s that those database drivers use are pretty much tied to the various versions of the database they connect to, so they have to be built by source using the right versions of the libraries for the right version of the database. *sigh*.

On the other hand… A solution arises… Java already has database support so it doesn’t really need Qt SQL C++ drivers. Instead we simply layered our database drivers on top of JDBC. I can’t take the credit for it, because it was mostly done by Harald, but at any rate, here it is.

Its a bit preliminary at this point, and we would love your feedback on bugs and suggestions. If we’re happy with the end result, this will be part of Qt Jambi 4.4.

Its available here:
http://labs.trolltech.com/page/Projects/QtJambi/JDBC

Enjoy

gunnar
Qt Jambi
Posted by gunnar
 in Qt Jambi
 on Friday, July 27, 2007 @ 09:08

A week or two ago, Eskil wrote a blog about how he’d been working on mixing AWT and Qt together in the same window. At the time he’d gotten to the point where we could embed a Qt widget inside an AWT component. Now we’ve gotten a bit further…

Based on the same approach we used for the Qt inside AWT embedding, we could also do the other way around pretty easy. The result is something along the lines of:

Qt Jambi and AWT

As opposed to Eskil, I decided to not show the picture of us with flowers in our hair that we took in San Francisco when we went for JavaOne earlier this year… What you’re seeing here is a QWidget with a grid layout with two QWidgets on the left, a QTextEdit with an html page and the CollidingMice example. On the right is the SwingSet demo. We also tried to embed a Java3D example there and that worked equally well.

The solution is not completely there yet, though. I did spend a day trying to get the focus handling between the two libraries right, and it was surprisingly non-trivial. AWT for instance doesn’t pass on the information that you’re doing SHIFT-Tab to do backwards traversal of the focus chain, so you need to figure that out based on the component that lost focus and where it is relative to the current one in the focus chain, and so forth… Lots of fun things. Right now its at a state where it works most of the time, but through mouse clicks and back/forward tabbing it breaks after a while so there is still work to be done.

The other issues are window activation, as we’re actually embedding the window natively and while the AWT component has focus, Qt becomes inactive, etc, but I’m not sure we’ll be able to get around that one. The other issue is OS X where AWT and Qt Jambi cannot run in parallel because of the Carbon event system not being thread safe.

Right now the code to get this example running looks something like this:

import com.trolltech.research.awt.*;
import com.trolltech.qt.gui.*;
import com.trolltech.launcher.*;

public class TestHost {

    public static void main(String args[]) {
        QApplication.initialize(args);

        QWidget root = new QWidget();

        QGridLayout layout = new QGridLayout(root);

        layout.addWidget(new QTextEdit(), 0, 0);
        layout.addWidget(new com.trolltech.examples.CollidingMice(null), 1, 0);

	SwingSet2 component = new SwingSet2(null, java.awt.GraphicsEnvironment.
                                            getLocalGraphicsEnvironment().
                                            getDefaultScreenDevice().
                                            getDefaultConfiguration());

        QAwtHost host = new QAwtHost(component);
        layout.addWidget(host, 0, 1, 2, 1);

        root.show();

        QApplication.exec();
        System.exit(0);
    }

}

All in all though, I find this pretty cool as it opens up for people to migrate from AWT / Swing to Qt Jambi and still being able to use thirdparty rendering libraries and the like.

gunnar
Qt
KDE
Qt Jambi
Posted by gunnar
 in Qt, KDE, Qt Jambi
 on Wednesday, June 06, 2007 @ 12:49

So the day has finally come… Whoohoo!!

Qt Jambi has been released in its final version, named 4.3.0_01. We
decided on calling it 4.3.0 after Qt 4.3.0 since thats the Qt version
the API matches and 01 for the jambi release of against Qt 4.3. Some
of the major new things is that the API is cleaned up
significantly. We removed the obsolete functions and fixed a lot of
documentation issues. We also got the webstart demo running on Mac OS
X and got the webstart to load plugins. Check it
out!

There are some minor visual changes. We added a splashscreen to the
Launcher with some nice transparency effects and drop shadow:


And we niced up the imageviewer preview just a little bit… Its not
that we think its more helpful to view an image which are reflected on
a mirror surface like that, but its easy and looks cool in screenshots
so why not.


Other than that there is not much more to say, other than.. Happy Coding!

-
The Qt Jambi Team

Comments Off
gunnar
Qt Jambi
Posted by gunnar
 in Qt Jambi
 on Thursday, April 26, 2007 @ 15:07

So we reached another beta release of Qt Jambi, press release here.
This is, at least according to plans, the final beta before we release
the final version later this summer. The team has done a tremendous
job in improving this version from the previous and I’ll mention a few
things in detail later, but first of all, I’d like to mention that
this release is dual licensed.

Thats right! The beta2 version of Qt Jambi is released under the preview license
and also under the GPL license. We spent a some time getting this to
work together with Apache Harmony Open Source Java SE in addition to
the Sun JDK which we already had. For details on the law, look in the faq.
The GPLing includes both the library and the Qt Jambi Generator, and I
hope you’ll find this to be good news..

So what other things has happened since the last time… In the last
release we enabled object garbage collection for all objects, which
resulted in a number of reports from people that gui elements, like
toolbar buttins and menu items, were disappering. In this release we
introduced a reference counting scheme that should minimize the chance
for this happening…

We also got rid of most of the poorly named operator_Xxx functions and
tried to replace them with more intuitive functions. For instance
QDataStream.operator_shift_left(byte []) has become
QDataStream.writeBytes(byte []). The generator also detects a number
of operator== and operator which is used implement the equals()
function and the java.lang.Comparable interface.

The Eclipse integration has received several additions in making it
load a whole lot better. In fact on most systems you don’t need to set
-Djava.library.path anymore, Qt Jambi will just figure it out based on
the location of the qtjambi.jar file. In addition to that we also got
a new wizard for making custom widgets in Qt Designer from Eclipse.

There are a number of other things too, but this is turning into a
changelog and I didn’t want that, so just check it out. Here’s the
webstart:

I feel really good about this release, just look how exited we are…

Håvard, Eskil and Gunnar

gunnar
Qt Jambi
Itemviews
Posted by gunnar
 in Qt Jambi, Itemviews
 on Tuesday, March 13, 2007 @ 16:58

Qt has a pretty nice architecture for doing MVC (Model/View/Controller) and being in the Qt Jambi team we wanted make Qt Jambi have access to all this. Unfortunatly we rather quickly ran into 2 big issues:

  • Performance. The Qt itemviews framework is heavily based on the QModelIndex class which is a light-weight object that is allocated on the stack and passed around (primarly) by reference. This means that in C++, allocating these and querying for them is (close to) a no-op. In Qt Jambi these QModelIndices become real Java objects. Java doesn’t have the concept of stack allocated objects (though there exists papers on escape analasys, etc, but this is theory and not always applicable), so a QModelIndex suddently becomes a little bit more heavy, pluss it needs to be garbage collected which also costs a little bit.
  • Usability. Hierarchical models are non-trivial. In Qt / C++, we had access to the QModelIndex::internalId() which is a void * which can be used to reference virtually anything in any kind of data model. In Java this maps to a java.lang.Object, but with this also comes the responsibility of memory managment. QModelIndex doesn’t reference count, for performance reasons, so by passing the java.lang.Object to the void * would mean that we either leak memory or risk that the object is collected by the garbage collector which will eventually crash. Neither of which are resonable alternatives…. Specially the parent() function becomes tricky to implement in Java.
  • So based on this we sat down and looked at ways to come up with a way to keep the QModelIndices on the C++ side for the performance critical parts and to improve the programming joy that is hierarchical data models. This basically led us QTreeModel, a subclass of QAbstractItemModel, which provides 3 virtual functions:

    public Object child(Object parent, int index)
    public int childCount(Object parent)
    public Object data(Object value, int role)

    As you can see we removed all the QModelIndex from the API, hid the parent() function and introduced the childCount() and child() functions for querying the structure and the data() function for querying the value.

    The data function also has convenience overloads like:

    public String text(Object value)
    public QIcon icon(Object value)

    For querying the most used data roles.

    To interoperate with the rest of the Itemviews framework we also provide mapping functions between QModelIndex and java.lang.Objects which is needed to interact with things like selections, collapsing/expanding, etc.

    public Object indexToValue(QModelIndex index)
    public QModelIndex valueToIndex(Object value)

    I have a little demo app that shows many of the different API aspects here and
    here, such as dynamically adding and changing nodes. Unfortunatly, this stuff is partially based on the in-house version of Jambi so you can’t run the first link just yet, but at least it gives you some insight into how easy it is to write tree models in Jambi now. The second link, is shipped as part of the current Qt Jambi beta.

    Who knows… maybe some of this will sneak its way back into Qt / C++ too someday ;-)

    gunnar
    Qt
    KDE
    Posted by gunnar
     in Qt, KDE
     on Tuesday, September 26, 2006 @ 14:27

    If you’ve looked through the Qt Jambi API, you’ll see that we don’t
    make use of the Java 5 feature of enumerators for mapping Qt/C++
    enums. Since we’re already using generics, auto-boxing and other Java 5
    features it probably seems a bit strange that we don’t use enums for
    mapping enums in Qt.

    The reason in short was: “We didn’t see a way how we could…”

    Why? Enums in Qt are used in a number of different ways. Some of them
    are bit flags that are passed to a QFlags< ...>, some are a list of
    special number and some are extensible id’s such as QEvent::Type, where
    we provide x number of default events and then users can define their
    own if they specify the event type to be higher than
    QEvent::User. Java enums on the other hand are _only_ enumerators, a
    list of named values from 0 to number_of_entries.

    We could easily solve the numbered enums used as bitmasks and special
    numbers, even a generics based QFlags which made typesafe flags. The
    problem of QEvent::Type and the extensible enum was a different
    issue. Java does not allow the programmer to create enums outside the
    enum declaration. However… After some hours of testing and
    prototyping we came up with a means to do this, of course while still
    preserving the use of the == operator and the possibility to use enums
    in switch statements.

    So from Tech Preview 3 of Qt Jambi you’ll start seeing support for real
    enums and real QFlags. To give you some idea, here’s how it will look:

    // Checking for enum values:
    switch (event.type()) {
    case MouseButtonPress: ...
    case MouseButtonRelease: ...
    case MouseMove: ...
    }

    // Custom event:
    QEvent.Type myEventType = QEvent.Type.resolve(QEvent.Type.User.value() + 1);

    // Creating, setting and unsetting bits in a QFlags
    QPainter.RenderHints hints = new QPainter.RenderHints();
    hints.set(QPainter.RenderHint.Antialiasing);
    hints.set(QPainter.RenderHint.SmoothPixmapTransform);
    painter.setRenderHints(hints);
    hints.unset(QPainter.RenderHint.SmoothPixmapTransform);
    graphicsView.setRenderHints(hints);

    That was a small update from the Java team, now its back to working
    with the JavaDoc support…

    Comments Off