6
votes

The Problem: When a QMainWindow or QDialog's corresponding .ui file has been altered in Qt Designer, the entire project must be cleaned and rebuilt in order for those changes to take effect: make clean then make. If the project isn't cleaned first, the changes will not reflect in the executable.

The Project Structure:

./
    project.pro
./include/
    MainWindow.h
    Main.h
./src/
    MainWindow.cpp
    Main.cpp
./ui/
    MainWindow.ui

The Source:

MainWindow.h:

#include <QMainWindow>
#include "ui_MainWindow.h"

class MainWindow : public QMainWindow, private Ui::MainWindow
{
    Q_OBJECT
    public:

    MainWindow();
};

MainWindow.cpp:

#include "MainWindow.h"

MainWindow::MainWindow()
{
    Ui::MainWindow::setupUi(this);
}

project.pro:

TEMPLATE = app
CONFIG -= debug release
CONFIG += qt debug_and_release warn_on incremental flat link_prl embed_manifest_dll embed_manifest_exe
QT += xml xmlpatterns

INCLUDEPATH += include/
UI_DIR = include/

FORMS += ui/MainWindow.ui
HEADERS += include/MainWindow.h include/Main.h
SOURCES += src/MainWindow.cpp src/Main.cpp

Note: Include guards and class members have been stripped out for terseness.

Update:

Assuming that we edit MainWindow.ui in Designer, save it, and run a make, the following shell commands are executed (on a Windows platform; equal commands are executed on a 'nix box too):

QTDIR\bin\uic.exe ui\MainWindow.ui -o include\ui_MainWindow.h
QTDIR\bin\moc.exe ... include\MainWindow.h -o build\moc\moc_MainWindow.cpp
MSVS\bin\cl.exe /c ... -Fobuild\obj\ moc_MainWindow.cpp 
MSVS\bin\link.exe ... /OUT:bin\target.exe

The uic header generator has been run, and the window has been moc'ed. Despite this the window remains unchanged in the executable.

Update #2:

I found these lines in the Makefile:

####### Compile

build\obj\MainWindow.obj: src\MainWindow.cpp

build\obj\main.obj: src\main.cpp

build\obj\moc_MainWindow.obj: build\moc\moc_MainWindow.cpp 

Bingo. MainWindow.obj rightfully depends on MainWindow.cpp, but not on moc_MainWindow.cpp. Changing the first line to build\obj\MainWindow.obj: src\MainWindow.cpp build\moc\moc_MainWindow.cpp rectified this whole issue.

However: the next time I run qmake it's going to nix me. What can I type in qmake to fix this permanently?

3
Actually, MainWindow.obj should depend on ui_MainWindow.h rather than moc_MainWindow.cpp. (moc_MainWindow.cpp will be compiled separately, and linked in at the link step.) Some thoughts: 1) Does your .pro file have a TARGET line? 2) You might need to add "core" and "gui" to the QT += line.piccy
@piccy: I can confirm that QT contains gui core xml xmlpatterns. TARGET = app.Jesse Hallam
I can't reproduce the unwanted behaviour you are seeing using Qt4.8.4 on Mac - if I look at the standard Qt examples, e.g. examples/designer/calculatorform, it works as expected, even after adding your UI_DIR and INCLUDEPATH specification. Does this standard example work for you? If so, you have something to work from/towards.Matt Wallis

3 Answers

0
votes

I believe that your UI_DIR should be set to ui, not include.

0
votes

It is interesting that you remove from the config both "release" and "debug," then add to the config "debug_and_release." Running debug_and_release adds both of those configurations in, but swaps their order in the CONFIG.

It doesn't sound like that would trigger the dependency problem you are seeing, but it is worth a try, as far as I'm concerned.

By the way, you can always give qmake a try without blowing away your Makefile. Just run "qmake -o Makefile.foo" and it will save it to another file.

0
votes

I've been struggling with problems like this for some time and found out that, DEPENDPATH needs to point all directories with generated files/project headers. Otherwise qmake may skip some headers while generating dependencies in Makefile. Try adding DEPENDPATH += include in your .pro file