Search code examples
qtqt5qt-designer

about the path to the header file for promote widget in QtDesigner


With Qt Designer, when I promote Widget, I've got some problem with ui_*.h files and the include of the headers of the promoted class. The problem appears under Linux where the headers of the promoted class is not found. Under Windows with MSVC 2017, no problem ...

Under windows, I put the relative path from the *.ui file folder.

Under Linux, it seems that I have to put the relative from the *.pro file folder ... not great if I have to reuse the widget in another project but it works

Anyone can explain ?

Thanks !

EDIT :

I have added example code bellow.

Do you need the generated ui_ file ?

You can see on this last file that the path to the mycombobox.h is relative from the root folder and not from the *.ui file folder.

This configuration seem to work under Windows too, but I would like to put the relative path from the *.ui file.

Structure of my folder :

in the root :

main.cpp
mainWindows.h
mainwindows.cpp

/Folder1 :
MyComboBox.h

/Folder1/Folder2 :
Form.h
Form.cpp

the main.cpp file :

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

The mainwindows.h :

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QHBoxLayout>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

The mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "folder1/folder2/form.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    centralWidget()->setLayout(new QHBoxLayout);

    centralWidget()->layout()->addWidget(new Form);
}

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

The /folder1/MyComboBox.h

#ifndef MYCOMBOBOX_H
#define MYCOMBOBOX_H

#include <QComboBox>

class MyComboBox:public QComboBox
{
    Q_OBJECT
public:
    MyComboBox(QWidget* parent=nullptr):QComboBox(parent)
    {
        addItem("My ComboBox");
    }

    virtual ~MyComboBox() {}

};

The /folder1/folder2/Form.h

#ifndef FORM_H
#define FORM_H

#include <QWidget>

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

private:
    Ui::Form *ui;
};

The /folder1/folder2/Form.cpp

#include "form.h"
#include "ui_form.h"

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
}

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

Last but not least, the Form.ui file :

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="MyComboBox" name="comboBox"/>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>MyComboBox</class>
   <extends>QComboBox</extends>
   <header>folder1/mycombobox.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

Solution

  • A possible solution is to use a .pri where the files that handle the form will be placed:

    ├── 52435692.pro
    ├── Folder1
    │   ├── Folder2
    │   │   ├── form.cpp
    │   │   ├── form.h
    │   │   ├── form.pri
    │   │   └── form.ui
    │   └── mycombobox.h
    ├── main.cpp
    ├── mainwindow.cpp
    ├── mainwindow.h
    └── mainwindow.ui
    

    form.pri

    INCLUDEPATH += $$PWD
    SOURCES += $$PWD/form.cpp
    HEADERS += $$PWD/form.h \
             $$PWD/../mycombobox.h
    FORMS += $$PWD/form.ui
    

    *.pro

    ...
    include(Folder1/Folder2/form.pri)
    

    form.ui

    ...
      <customwidget>
       <class>MyComboBox</class>
       <extends>QComboBox</extends>
       <header>../mycombobox.h
    </header>
      </customwidget>
    ...
    

    Also, when using INCLUDEPATH += $$PWD in the .pri it is no longer necessary to include the complete path when importing the form:

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QVBoxLayout>
    #include "form.h" // <--- before "folder1/folder2/form.h"
    ...
    

    The complete example can be found in the following link