Recently I’ve been spending much time developing “wwWidgets” – my set of custom widgets for Qt4. Among others, the set contains widgets that are multipage container widgets that have to be treated in a special way – by providing an extension to Designer that tells it how to add or remove new pages to the widget.
Unfortunately Designer seems to be having much trouble with that currently. I could even call it the biggest misdesign in Qt4 (at least the biggest I’m aware of). Container widgets need to be handled on two levels – first Designer has to save some information about the custom widget in the UI file and the UIC has to process the file and generate C++ code that does the widget layout. The problem is that Designer doesn’t provide enough information for UIC to generate code that adds pages to multipage container widgets. The “misdesign” is that currently UIC checks the class name of the container widget and if it is a subclass of QTabWidget, it calls addTab(child, label), if it is a subclass of QStackedWidget, it calls addWidget, but for all other widgets it ignores the multipage nature of the widget and just makes a parent-child relationship between the container and its pages. As one might expect it leads to unpredicted and unwanted behaviour.
I contacted Trolltech about it and they said they were working on it and it should already be solved in Qt4.3 beta. Unfortunately class and method names are still hardcoded into UIC. For the time being I suspended dealing with the problem as I don’t want to reinvent the wheel trying to come up with a fix if Trolls are already working on it (it means I’m giving them a chance to improve the design).
However this doesn’t mean I’m not thinking about possible solutions or temporary workarounds and I came up with three possible fixes.
The first (and probably the best) idea is to somehow store the signatures of methods needed by the widget to manipulate its pages in the xml description of the custom widget added to each UI file using the widget. Then UIC could use that information to generate code that would call a proper method to add pages to widgets. The only question is, how to retrieve such data. According to me there are two possibilities. First involves the custom widget interface that accompaniates each widget plugin. There is a reserved method codeTemplate which was probably intended to do exactly the thing needed here – provide a template code to be used by UIC. The second possiblity is to use Q_CLASSINFO() macro to embed such information directly in the widget itself in a simmilar manner.
The second method is somewhat simpler – let’s just assume the method to add new page has to follow some well known naming scheme or that the container widget has to implement some interface which serves the purpose of letting UIC use well known (hardcoded) method names to manipulate widget pages.
The last method is merely a workaround that can be applied with existing Qt versions without the need to patch any Qt code. Qt objects receive a special event (QChildEvent) that informs that a child was added or removed from the object. It could be used to intercept the pages inserted with the faulty behaviour of UIC so that the widget itself could incorporate the child as its page. Of course it means it wouldn’t be possible to add child widgets to the widget “the traditional way” as all widget children would be treated as pages.