D2 GUI Libs

Eldar Insafutdinov e.insafutdinov at gmail.com
Sun Dec 13 05:12:39 PST 2009


Andrei Alexandrescu Wrote:

> Eldar Insafutdinov wrote:
> > Right now we are working on a next QtD version. We dropped support
> > for D1, it is D2 only. I believe Qt suits all your requirements very
> > well. It's performant - we try to emulate as many C++ types using D
> > structs as possible, for drawing purposes. So types like QPoint - are
> > D structs and for drawing lines you can pass D array directly. No
> > perfromance hit. But of course we cannot avoid all of them, it is
> > still a binding. Regarding the license, Qt itself is LGPLed, QtD is
> > boost. you don't have to put any attribution. About stability of APIs
> > - Qt4 is stable within the major version. At the moment we are
> > working on signals/slots implementation. It is mostly complete, but
> > syntax may change. It will hopefully change once and stay forever.
> > 
> > I would say that QtD is in the state close to that of D2, almost
> > there, but not quite ready yet. But we intend to release the next
> > version, which will be ready to use earlier than D2 anyway, I would
> > say within a month.
> 
> I salute the decision of going with D2, as well as that of using the 
> Boost license. If there is anything in the language that prevents you 
> from getting things done, please let us know. The availability of QtD 
> concurrently with that of D2 will hopefully push both forward.
> 
> Andrei

Thanks for cooperation. I don't want to sound like I've given the right to ask for features, because I am working on a particular D project. But at the same time, indeed, while working on this project I found many things that I would like to be improved. Here are some of them:

1) You may know the concept of signals and slots in Qt. Consider the following snippet:

class Test : QObject
{
    mixin Signal!("signal_1(string)");    

    mixin Slot!("slot_1(string str)");    
    void slot_1(string str)
    {
        writefln("slot_1 invoked with ~ " str);
    }

    mixin Q_OBJECT;
}

In Qt objects, that inherit from QObject are capable of having signals and slots and participate in connections. In the current scheme mixins of Signal and Slot template mix some static information into the class. The class is then scanned when Q_OBJECT template is mixed in and the proper meta-information is generated to register signals and slots in the Qt type system.
As you see, this declaration is a bit ugly. In particular defining a slot requires to duplicate its signature in a mixin. What would really be awesome is a mechanism allowing something like:

    @Slot
    void slot_1(string str)
    {
        writefln("slot_1 invoked with " ~ str);
    }
I.e we need annotations. But I am not sure how this will work. One of the possible solutions will be that @Slot expands into mixin Slot!(symbol, AnnotationArg1, ...).  

But I have to say, that expanding annotations into mixins might not be a good idea. Annotations could rather be implemented by aggregating the data with symbols instead. I think it will be more clean than the current scheme we chose with mixing in and scanning data. Instead you have some data aggregated with declarations. Using compile time reflection you iterate over the symbols, look for annotations, extract them and do whatever you want with it. Say if we introduce traits(getAnnotations, symbol) feature and it will return a construct like StaticTuple!(SealedTuple!("annotationName", AnnotationArg1, ...), ...); it will be sufficient. We should discuss it more anyway.

2) Second problem in this declaration is that in order for Q_OBJECT template to see all signal and slot declaration you have to put the mixin after all of them, like in example. This is absolutely a stupid requirement. Again it could be solved either by annotations:

@Q_OBJECT
class Test : QObject
{ ... }

which will again expand into a mixin in the class body after all of the declarations,
or by the feature you suggested a while ago - mixin (Derived), which will mix in some stuff to all sub-classes of QObject automatically. 

3) To continue the first paragraph signals should also get some love. If we have this for slots:

@Slot
void slot_1(string str)
{
...
}

I would also like to have something like:

@Signal
void signal_1();

What it will effectively means, is that we are declaring a method without a body and aggregate some meta data with it using annotation. The body for the signal instead of being generated by the mixin Signal!(...) like in the first snippet, will be generated at the very end by mixin Q_OBJECT (or with a mixin Derived)

Essentially we should allow separating function declaration and definition to allow that, currently dmd just asserts trying to compile this:

class Test
{
   void foo();
   void foo() {}
}

So the final refined declaration of a class with a signal and a slot from the first snippet using proper annotations, mixin Derived in the base class and allowing for separating function declaration and definition will look like:

class Test : QObject
{
    @Signal
    void signal_1(string);    

    @Slot
    void slot_1(string str)
    {
        writefln("slot_1 invoked with " ~ str);
    }
}

Much nicer, isn't it?

4) __traits should access the data mixed in by template mixins. Otherwise we have to use dirty template trickery.

5) As QtD uses templates extensively, it would be really helpful if the compiler gave better error messages about template instantiation errors. Specifically, static assert(false, ) is often used to give the user a message about the error but it is sometimes very hard to find the place of outer instantiation. Propagating the FILE_ and __LINE__ to nested instantiations is impractical. There has been this patch by Don for a long time that fixes the 'static assert' issue: http://d.puremagic.com/issues/show_bug.cgi?id=2816. We'd really like to have it applied. See also http://d.puremagic.com/issues/show_bug.cgi?id=2902, http://d.puremagic.com/issues/show_bug.cgi?id=2510.

6) Various, various compiler bugs. I'm not joking here, I hit dmd bugs every single day I work on qtd. It makes it very difficult to cut down to sensible testcases, because of the size of the library. I filed some bugs, I used all my votes in bugzilla, but neither of those got any update within last 2 months. That's a pity. I am sure many other people have similar experience.

The main one is probably forward references bug. That's why I have to use patched version of dmd (done not by me). Work on it is still in progress, and when the author of the patches finishes it and submits them to the bugzilla, we would need apply them somehow, as otherwise official dmd will not compile QtD.



More information about the Digitalmars-d mailing list