Search code examples
c++qtclass-namesuic

Multiple Ui_Dialog definitions due to multiple *.ui files?


I'm working on a RaspberryPi with a 3.5 inch LCD screen. I have a Qt 5 based application that operates in kiosk mode without a title bar. The app uses the entire 320x480 screen. I am trying to add a second dialog that is displayed when the user clicks a button on the main dialog window.

Each dialog is designed using Qt Designer. Each dialog has a *.ui file that sets the dialog size and adds a button. The *.ui file is uic'd or moc'd into a header and source file:

$g++ -c -pipe -g3 -O1 -O2 -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG -DQT_UITOOLS_
LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/x86_64
-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtUiTools -isystem /us
r/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/
qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -isystem /usr/in
clude/libdrm -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o dialog1.o 
dialog1.cpp
In file included from dialog2.h:7:0,
                 from dialog1.h:8,
                 from dialog1.cpp:1:
ui_dialog2.h:22:7: error: redefinition of ‘class Ui_Dialog’
 class Ui_Dialog
       ^~~~~~~~~
In file included from dialog1.h:7:0,
                 from dialog1.cpp:1:
ui_dialog1.h:22:7: note: previous definition of ‘class Ui_Dialog’
 class Ui_Dialog
       ^~~~~~~~~
In file included from dialog2.h:7:0,
                 from dialog1.h:8,
                 from dialog1.cpp:1:
ui_dialog2.h:50:11: error: redefinition of ‘class Ui::Dialog’
     class Dialog: public Ui_Dialog {};
           ^~~~~~
In file included from dialog1.h:7:0,
                 from dialog1.cpp:1:
ui_dialog1.h:50:11: note: previous definition of ‘class Ui::Dialog’
     class Dialog: public Ui_Dialog {};
           ^~~~~~
Makefile:445: recipe for target dialog1.o failed
make: *** [dialog1.o] Error 1

The problem seems to be the way the *.ui file is translated:

$ cat ui_dialog1.h | tail -n 7
namespace Ui {
    class Dialog: public Ui_Dialog {};
} // namespace Ui

And:

$ cat ui_dialog2.h | tail -n 7
namespace Ui {
    class Dialog: public Ui_Dialog {};
} // namespace Ui

I know the problem, but I am not sure how to fix it under Qt tools. The tools need to use a unique namespace or unique class name for each *.ui file.

How do I fix the problem?


A MCVE is available at Noloader | qt-ui-dialog GitHub. The MCVE be cloned with:

git clone https://github.com/noloader/qt-ui-dialog

The problem can be reproduced with:

cd qt-ui-dialog
make clean && qmake && make

Solution

  • An ui_something.h header must be included in something.cpp source file, not in something.h header. Looking at your compiler output, it seems you're including ui_dialog1.h in dialog1.h, which is wrong: include it in dialog1.cpp, instead (same applies to other dialogs).

    Be sure to forward declare the Ui namespace and class in the header, though. In both your headers, add this lines before the dialog class declaration:

    namespace Ui {
        class Dialog;
    }
    

    This means you must use a pointer to this Ui::Dialog class, so it has to be:

    class Dialog1 : public QDialog
    {
       /* ... */
    private:
        Ui::Dialog * ui;
    };
    

    and, accordingly:

    Dialog1::Dialog1(QDialog *parent)
        : QDialog(parent), 
          ui(new Ui::Dialog)
    {
        ui->setupUi(this);
    }
    

    cleanup:

    Dialog1::~Dialog1()
    {
        delete ui;
    }