Custom Layout Managers

  • I'm working on some custom layout managers and the subject isn't covered much in the "doc":
    I also looked in my copy of "C++ GUI w/ Qt 4", but they aren't discussed.

    I've gotten a couple up and running and my confusion comes from adding placement data to the signatures of
    addWidget(Widget*) and addItem(QLayoutItem*).

    The doc says about addItem(QLayoutItem*):

    bq. It is used by QLayout::add(), by the QLayout constructor that takes a layout as parent. If your layout has advanced placement options that require parameters, you must provide extra access functions such as the row and column spanning overloads of QGridLayout::addItem(), QGridLayout::addWidget(), and QGridLayout::addLayout().

    QGridLayout's addWidget(Widget, data...) calls @QWidgetItem *b = QLayoutPrivate::createWidgetItem(this, widget);@
    to create the QWidgetItem, and that returns: @new QWidgetItemV2(widget);@ What is that? Since QLayoutPrivate isn't accessible to my subclasses, should I just use new QWidgetItem(widget) or do I need a QWidgetItemV2?

    And finally, I know addItem(QLayoutItem*) must be implemented because it's pure virtual, but does it have to do anything?
    If I left it empty what would I break? Would the following (adapted from QGridLayout) be correct for a layout with placement data:

    void MyLayout::addWidget(QWidget *widget)
    // can I leave this empty?

    void MyLayout::addWidget(QWidget *widget, PlacementData data)
    QWidgetItem *b = QLayoutPrivate::createWidgetItem(this, widget); // what do I do here?
    addItem(b, data);

    void MyLayout::addItem(QLayoutItem *item, PlacementData data)
    // add item and data to my layout data structure

    void MyLayout::addItem(QLayoutItem *item)
    // can I leave this empty?

  • Hi,

    did you look at this example: "flow Layout":

    It's the only thing I know for custom layouts so far.

    Do you really need to create a custom layout?

  • That Flow Layout example doesn't include an overloaded addItem with placement data.
    I'm just going to make addWidget and addItem empty and use QWidgetItem(widget).
    This seems to work for now.

    In Java it was just a stupidly "simple interface": to make layouts. The add(Component, Object) method already took an Object for your own placement data (I'm aware that C++ doesn't have a single Object super class so this wouldn't be as easy).

    I don't know why in Qt the Layouts have to return iterators for getting and removing in natural ordering, or why they wrap the Widgets in a WidgetItem??? A couple methods could suffice. With QLayout I don't know what's optional or necessary.

    Do you really need to create a custom layout?

    They've always been so simple that they were easier to write than to nest. Plus, I like to prototype interesting desktop designs. -Shrug-

  • I need a custom layout, and I haven't been able to figure out how to get it to work with my own subclass.

    I currently am using a QVBoxLayout to lay out a bunch of tools vertically. What I would like to happen is if there is no room for some widgets at the bottom, they wrap to another column to the right. This means the widget should expand horizontally only if there isn't enough room vertically - keeping in mind that the vertical height could change due to sashes in the parent layout.

    Unfortunately I can't see any way to do this since I appears I would need to make the layout wider if I detect some items will go off the bottom in the setGeometry() call, which would make setting the geometry recursive. Is there a way to rectify this?

  • Sounds like the flow layout, only in another direction. You should be able to adapt the example to work top to bottom, and then left to right instead.

  • Andre - that's what I had originally thought, but when looking at the "heightForWidth" stuff it occurred that I would need the opposite - widthForHeight - to make it work right. Am I wrong about that?

  • No, you might be right in that actually.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.