[SOLVED] Qt Creator - promoting top level widget



  • I have some business logic in a subclass of QWidget. I now want to create a new QWidget in which the top level QWidget is promoted to my subclass.

    This works for me if the .ui file just has the top level "class" attribute set to my subclass, but is there a way to get that result through Qt Creator? I realize I can insert another QWidget and promote it but I really just want to promote the top level QWidget.

    I'm using Qt Creator 3.0.0, by the way.



  • To clarify:

    Let's say I have a class called MyWidget (with MyWidget.h and MyWidget.cpp). I want to create a new .ui class like MyForm (.ui, .h and .cpp) which would subclass MyWidget. So I'd be able to reference MyWidget's protected members and override methods inside MyForm.


  • Moderators

    Hi,

    What did you intend to do with the *.ui file?

    You can't edit a promoted widget in Qt Designer. Therefore, if you promote the top-level widget, then you can't edit the *.ui file at all.

    Qt Designer is for widget Composition, not Aggregation and not Inheritance. If you subclass a widget, make your changes/additions in C++.



  • I intend to add specific layouts and widgets to that .ui with the designer. I want to subclass for the business logic but also want to work with the designer.


  • Moderators

    Hi,

    You cannot use Qt Designer to modify a subclassed widget.

    [quote author="frankiefrank" date="1389540335"]I intend to add specific layouts and widgets to that .ui with the designer.[/quote]Then you want to create a completely new widget instead of subclassing an existing widget.

    [quote author="frankiefrank" date="1389540335"]I want to subclass for the business logic but also want to work with the designer.[/quote]Consider redesigning your system: Widgets should contain GUI logic but not business logic. Move the business logic to a non-GUI class that can be shared between MyWidget and MyForm.



  • I need the same but not for a business logic. I want to change or upgrade QWidget behavior. For the first I want to make saveGeometry/restoreGeometry between show() and hide() for couple of top-level general widgets. Later may be some other similar features. How to avoid duplication of code?

    The only way I see is to make subclass of QWidget without an ui form - QwidgetWithoutUi, add some methods in it. Then create a subclasses of QWidget with ui form. And then:
    @firstQwidgetWithUi->setParent(qWidgetWithoutUi_1);
    otherQwidgetWithUi->setParent(qWidgetWithoutUi_2);
    .....@
    and so on.

    In one hand we have duplication of QWidget and 2 instead of 1 pointers to control one window but in other hand we have no uncomfortable decomposition of ui hierarchy in Qt Designer.

    Is there another solution?


  • Moderators

    Hi frankiefrank and Kroll,

    I was mistaken before. Qt Designer can be used to create UI layouts without attaching it to business logic: Just create a *.ui file by itself, without a *.h or *.cpp. Then, attach the *.ui file to your QWidget subclass by following the instructions at http://qt-project.org/doc/qt-5/designer-using-a-ui-file.html . Sorry for the confusion.



  • Thanks for that link JKSH. But for me it was actually better to separate the business logic.



  • If I change class="QWidget" to class="MyWidget" in .ui and reopen it then list of widgets in Designer will be gray and not available to use. Realy, Designer may only work with native widgets.

    Then I went on the other side. No need RCM and Promote.

    1. As usually create new c++ subclass "Widget" from QWidget (widget.h, widget.cpp)
    2. As usually create new ui form class "MyClass" from QWidget (myclass.h, myclass.cpp, myclass.ui)
    3. A little bit of changes in myclass.h and myclass.cpp

    myclass.h
    @#ifndef MYCLASS_H
    #define MYCLASS_H

    #include "widget.h" //there was a <QWidget>

    namespace Ui {
    class MyClass;
    }

    class MyClass : public Widget //was: pyblic QWidget
    {
    Q_OBJECT

    public:
    explicit MyClass(Widget *parent = 0); //was: (QWidget *parent = 0)
    ~MyClass();

    private:
    Ui::MyClass *ui;
    };

    #endif // MYCLASS_H@

    myclass.cpp:
    @#include "myclass.h"
    #include "ui_myclass.h"

    MyClass::MyClass(Widget *parent) : //was: (QWidget *parent)
    Widget(parent), //was: QWidget(parent)
    ui(new Ui::MyClass)
    {
    ui->setupUi(this);
    }

    MyClass::~MyClass()
    {
    delete ui;
    }@

    Works as if it was a promoted. I don't see any issues. In Widget files I can reimplement the behavior of QWidget for Widget subclasses. And in files of Widget subclasses I have access to protected members of it and also can override methods of Widget. Strange that Creator does not have this option in creating of ui form class.



  • Thanks for that - and for the clear code example!


Log in to reply
 

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