[Solved] Using a .ui file in another class?



  • Hi,
    I have a MainWindow class in which I have already used a .ui file for creating the Main Window of my application. Now I want to create an About Dialog. I created the same in a .ui file (without creating a separate class for the same). However I am unable to use the .ui file in my Main Window class.

    So my question is how should I use a .ui file in any other class?


  • Moderators

    I'm not sure I understanded correctly, but basically you should keep every class and its related gui definition in separate file, so for example:

    mainwindow.h, mainwindow.cpp, mainwindow.ui
    dialog1.h, dialog1.cpp, dialog1.ui
    dialog2.h, dialog2.cpp, dialog2.ui

    "About dialog" is a separate logical entity so I don't think it's a good design to stuff it into the main window anyway.

    Also, if your about dialog is simple enough, you can use "QMessageBox::about()":http://qt-project.org/doc/qt-5.0/qtwidgets/qmessagebox.html#about. It takes a "text" parameter which accepts html formatting so you can go pretty wild with it.



  • Hi Chris, Thanks for replying.
    OK, I will create a separate class for the About dialog.

    But still I am curious as to how can I use dialog1.ui in mainwindow.cpp if dialog1.h, dialog1.cpp are not created?


  • Moderators

    Well, not to say that it's impossible but it has a little sense to be honest to use two .ui files for one class.
    .ui file describes (in xml) how the ui looks like. Lets say the form in that .ui file is called MyForm. During the build a "uic" tool is called on that file to generate ui_myform.h file that contains the actual c++ code to generate this ui at runtime. This ui_myform.h file is then included in your own (usually created with wizard) myclass.cpp file and a class member Ui::MyClass ui; is added. Then, in the constructor of your class a method ui.setupUi(this); is called to tie the generated code with your class.

    So, to use two different .ui files you would have to add another include like "ui_myotherclass.h" that corresponds to myotherclass.ui file, add a class member Ui:MyOtherClass ui2, and call setupUi() on it. The problem here would be that the two setupUi calls would fight each other when given the same parent (this). It makes little sense to call two different setup methods on a single widget. You might call setupUi with another widget as a param (like dialog), but this is hardly a supported scenario and you would probably confuse any other guy reading your code. The proper OO behavior here is to separate dialogs into their own classes. Makes it easier to find things and follow the code flow.



  • Thanks a lot Chris!
    I am fully satisfied now.
    I just wanted to know whether it was possible to use 2 .ui files for the same class.
    Thanks man!
    Will now create separate classes for separate .ui file.



  • @Chris-Kawa Well, confirming to OOP , using multiple dialogues ..... is the name Space! is still possible, the key idea is that ui are constructed with name space in their headers.

    So, looking at the dialog class ( .h) file, we find the name space declaration, something like:

    namespace Ui {
    class dialog_1;
    }
    

    and here in the same .h file, the class is declared, some thing like:

    class dialog_1 : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit dialog_1(QWidget *parent = 0); // Constructor of first dialog class
        ~dialog_1(); // destructor of first dialog class 
    
    private:
        Ui::dialog_1*ui; // Note this!! the declaration of the "ui"
    };
    

    it would be possible then, in an OOP sense to extend that name space with a second class, whose body is still defined in this same .h file
    some thing like this:

    namespace Ui {
    class dialog_1;
    class dialog_2;   // instead of creating seperate CPP and header for this dialog, its added to the name space, then 
                                    // here we define the class body and its constructor as below
    }
    class dialog_1 : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit dialog_1 (QWidget *parent = 0);
        ~dialog_1 ();
    
    private:
        Ui::dialog_1 *ui;
    };
    class dialog_2 : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit dialog_2 (QWidget *parent = 0);
        ~dialog_2 ();
    
    private slots:
    
    
    private:
        Ui::dialog_2 *ui;
    };
    

    and then ... in the CPP file (only one file for both dialoges!)

    dialog_1 ::dialog_1 (QWidget *parent) :
        QDialog(parent),
        ui(new Ui::dialog_1 )
    
    {
        ui->setupUi(this);
    }
    
    dialog_1 ::~dialog_1 ()
    {
        delete ui;
    
    }
    
    dialog_2 ::dialog_2 (QWidget *parent) :
        QDialog(parent),
        ui(new Ui::dialog_2 )
    
    {
        ui->setupUi(this);
    }
    dialog_2 ::~dialog_2 ()
    {
        delete ui;
    
    }
    void code_to_call_dialog_2_from_within_dialog_1()
    {
       dialog_2* dialog_2_called_by_slot_in_dialog_1= new dialog_2 ; // and it works smooth
        gsd->exec();
    }
    

Log in to reply
 

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