Why aren't Qt layout managers widgets?



  • My friends,

    I am a new student of Qt, and I am confused by an aspect of its widget and layout architecture.

    My question is this: why aren't layout managers widgets?

    The Q*Layout classes do not inherit from QWidget, for example.

    What is the architectural reason for Qt having layout managers be so separate from widgets?

    Are there benefits derived from keeping them separate?

    Or is it just a historical oddity, because Qt was such an early pioneer and changes are unwanted to retain compatibility?

    I have used other UI libraries where layout managers are just widgets like any other widget. They are just container widgets that control the sizing and positioning of their children widgets in some specific way. They can be nested just like any other widgets can be. There is just one unified hierarchy of widgets, some of which are things like buttons and inputs, while others are focused on layout.

    Qt's architecture with separate widgets and layout managers, where the layout managers aren't themselves widgets, seems so unnecessarily complicated compared to these other libraries that treat layout managers as themselves being widgets just like any other widget.

    I don't think I will ever be able to use Qt properly unless I really have a good understanding of why Qt treats widgets so separately from layout managers.

    Your friend in learning,
    Johnny


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    For the basics of layouting see the Layout Management chapter of Qt's documentation.

    What UI libraries are your comparing Qt to ? Are you sure their concept of widget matches the one from Qt ?

    As for why exactly it was designed like that, you should ask that on the interest mailing list. You'll find there Qt's developers/maintainers. This forum is more user oriented.


  • Qt Champions 2016

    Hi
    What would be the benefit of layouts being widgets ? They share none of the
    charistics of a Widget. Have visual representation, can have colors and stylesheets - can be interacted with by end user, can receive OS events. so a lot of the structure would be wasted space.
    I never wished they were Widgets so im asking out of curiosity
    what is it about them being more like a helper class available via layout() and
    generally just out of the way in a good sense ? (you dont like)
    Also since any Widget can be a container and have a layout, its just much more flexible than
    having a few designated container types as other GUI frameworks offers. (IMHO)



  • @SGaist FOX is one such library. It is also a C++ library and although its not identical to Qt, I think it is quite comparable. It also has similar layout managers but they are widgets rather than being a separate concept. The inheritance hierarchy for a FXHorizontalFrame (lays out its children widgets horizontally) or a FXMatrix (lays out its children widgets in a grid) is quite similar to that of a FXButton (a typical clickable button).

    With FOX, widgets and layout managers come together seamlessly in an application, forming a single tree consisting of nested widgets.

    I'm not saying that Qt is doing it wrong, and I don't expect Qt to change.

    I just want to understand if Qt's approach is better in some way that I'm just not aware of.

    My first impression of it is that Qt's approach is much more muddled and unclear than the approach used in a library like FOX, where there isn't a distinction between "widgets" and "layout managers"; they're all just widgets.



  • @mrjj My other comment describes what I mean.

    One benefit of layout managers being widgets is that there's a single, clear, parent-children hierarchy of widgets, where the layout managers fit in cleanly within this tree of widgets within a UI in code and on-screen. The layout managers are just widgets that contain other widgets, with these other widgets possibly being other layout manager widgets.

    So far I have found Qt's approach more confusing, for example with reparenting happening at runtime because layout managers aren't just container widgets that would naturally be parents of their laid-out children widgets.

    Instead of one clear tree of parent-children relationships between widgets in the C++ code and on-screen, I end up creating a lot of unparented widgets, and then separately the layout managers forming the relationships at runtime, making the relationship between the C++ code and the resulting UI much less obvious than with other toolkits that I've used.

    I think that layout managers do exhibit far more of the characteristics of widgets than you may think. They do have a visual representation; they are any space between children widgets, for example. This space could be colored or styled in some way. A user could click in this intermediate area. The layout manager could be resized.

    I can see what you're saying about Qt's approach potentially being more flexible. But from what I've seen so far, this flexibility comes at the expense of clarity. While in a toolkit like FOX, for example, I would just use a single FXHorizontalFrame widget, in Qt I find myself using a generic QWidget along with a QHBoxLayout. It's more typing, and the widget relationships aren't as obvious in code.

    I'm not saying that Qt is wrong, and I don't expect it to change. I'm just trying to understand it and its design rationale better.


  • Moderators

    Hi @JohnSmithFromBritain, and welcome!

    @JohnSmithFromBritain said in Why aren't Qt layout managers widgets?:

    I don't think I will ever be able to use Qt properly unless I really have a good understanding of why Qt treats widgets so separately from layout managers.

    You might find it more comfortable to work with Qt Quick than with Qt Widgets, then: https://doc.qt.io/qt-5.10/qtquick-layouts-layouts-qml.html In Qt Quick, Layouts inherit Item (where Item is somewhat analogous to QWidget)

    Anyway, there is a well-defined relationship between Layouts and Widgets in the Qt Widgets world, just a different kind from what you're used to:

    • In the FOX architecture, a Layout class is-a Widget class. In other words, Widget is the ancestor class of Layout.
    • In the Qt architecture, QLayout, QWidgetItem and QSpacerItem are sibling classes -- these 3 classes inherit QLayoutItem. In other words, Layouts, Widgets, and Spacers are 3 different things that can be managed by a layout manager.

    A philosophical analogy from human relationships: Some parents want their children to treat them as elders; other parents want their children to treat them as friends. There are ongoing debates regarding which approach is "better".

    Are there benefits derived from keeping them separate?

    One thing that comes to mind is: A QWidget is a "heavy"/"expensive" class. QLayout and QSpacerItem are more lightweight. This doesn't matter on today's PCs, but could be significant in a small embedded device.

    is it just a historical oddity, because Qt was such an early pioneer and changes are unwanted to retain compatibility?

    There have been multiple breaking changes to Qt in the past, to improve architecture. There will be more breaking changes in the future, when we transition from Qt 5 to Qt 6.

    However, I'm guessing there hasn't been a strong incentive to change the Qt Widgets architecture, which has worked well in the past.

    @JohnSmithFromBritain said in Why aren't Qt layout managers widgets?:

    Instead of one clear tree of parent-children relationships between widgets in the C++ code and on-screen, I end up creating a lot of unparented widgets, and then separately the layout managers forming the relationships at runtime, making the relationship between the C++ code and the resulting UI much less obvious than with other toolkits that I've used.

    You don't need to start with unparented widgets. You can specify the parent at creation time for clarity:

    // All objects are parented to MyWidget at instantiation
    MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
    {
        auto layout = new QHBoxLayout(this);
        auto lineEdit = new QLineEdit("C:/Folder/", this);
        auto button = new QPushButton("Browse...", this);
    	
        layout->addWidget(lineEdit);
        layout->addWidget(button);
    	
        this->setLayout(layout);
    }
    
    // Or similarly...
    QWidget topLevelWidget;
    auto layout = new QHBoxLayout(&topLevelWidget);
    auto lineEdit = new QLineEdit("C:/Folder/", &topLevelWidget);
    auto button = new QPushButton("Browse...", &topLevelWidget);
    
    layout->addWidget(lineEdit);
    layout->addWidget(button);
    
    topLevelWidget.setLayout(layout);
    topLevelWidget.show();
    

    they are any space between children widgets, for example. This space could be colored or styled in some way. A user could click in this intermediate area. The layout manager could be resized.

    In Qt, the space in between child widgets belongs to the parent widget. So, the parent widget can handle the colours/styles/clicks/etc. (or, we can stick another widget there to handle the colours/styles/clicks/etc. if we prefer)

    While in a toolkit like FOX, for example, I would just use a single FXHorizontalFrame widget, in Qt I find myself using a generic QWidget along with a QHBoxLayout. It's more typing, and the widget relationships aren't as obvious in code.

    I think neither FXHorizontalFrame in C++ nor QWidget+QHBoxLayout in C++ can compete with a graphical WYSIWYG tool. Personally, I prefer the workflow of using Qt Designer to implement and edit my GUI layouts (there's almost no typing required!). Once you get used to the graphical workflow, the underlying C++ code becomes less relevant.


Log in to reply
 

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