PDA

View Full Version : Generated UI header incorrectly includes class header?



droneone
14th June 2012, 02:26
Hello all,

I'm having an issue wherein for a particular .ui file, the auto-generated ui header is trying to include the core class header, and failing.

That is, I have a QWidget-derived class, called slimWindow, and when building via Qt Creator, it generates the ui_slimwindow.h file, which tries to #include "slimwindow.h", which of course fails (that file doesn't get moved to the .ui directory during build).

The odd thing is, this error started when the class was moved from one subdirectory to another, even though the .pri file including it is correct, and everything works otherwise. I have many other ui files, and none of the rest do this. Telling in the symptoms is that the generated ui header doesn't declare the new object as a QWidget, like all of the other QWidget-derived headers, but instead declares it an instance of its own class, see:



/************************************************** ******************************
** Form generated from reading UI file 'slimwindow.ui'
**
** Created: Tue Jun 12 17:19:52 2012
** by: Qt User Interface Compiler version 4.8.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
************************************************** ******************************/

#ifndef UI_SLIMWINDOW_H
#define UI_SLIMWINDOW_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGridLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLineEdit>
#include <QtGui/QPushButton>
#include <QtGui/QSpacerItem>
#include <QtGui/QTableView>
#include <QtGui/QTextEdit>
#include "slimwindow.h"

QT_BEGIN_NAMESPACE

class Ui_SlimWindow
{
public:
QGridLayout *gridLayout_2;
QGridLayout *gridLayout;
QHBoxLayout *horizontalLayout_2;
QSpacerItem *horizontalSpacer;
QLineEdit *commandInputLine;
QPushButton *goButton;
QHBoxLayout *horizontalLayout_4;
QTableView *historyTableView;
QTextEdit *commandResults;

void setupUi(SlimWindow *SlimWindow)

...


Whereas, for all other QWidget-derived classes with ui files, the generated code looks as follows:




...

#include <QtGui/QLabel>
#include <QtGui/QListView>
#include <QtGui/QPushButton>
#include <QtGui/QScrollArea>
#include <QtGui/QSpacerItem>
#include <QtGui/QSpinBox>
#include <QtGui/QToolButton>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_filmWindow
{
...

QPushButton *pushButton_11;
QPushButton *pushButton_10;
QPushButton *pushButton_9;

void setupUi(QWidget *filmWindow)

...


This happens on both OSX and Windows during compile. I know that I can change include paths and the issue will "disappear", but that seems like a cover-up over a bigger problem. Has anyone seen similar behavior before? I saw one post regarding it, but the suggested, and followed, solution was to cover up the issue by modifying the include paths so that including a file not in the current directory would work.

Without posting mountains of code, as the project is fairly complex I'm hoping the following parts will be sufficient in pointing out what I might've done wrong?:

slim.pri:



DEFINES += QT_USE_QSTRINGBUILDER

HEADERS += \
slim/slimwindow.h \
slim/SlimFileHandler/slimfilehandler.h

SOURCES += \
slim/slimwindow.cpp \
slim/SlimFileHandler/slimfilehandler.cpp

FORMS += \
slim/slimwindow.ui


slimwindow.h:



#ifndef SLIMWINDOW_H
#define SLIMWINDOW_H

#include <QWidget>
#include <QString>

#include "MoCoBus/omcommandbuffer.h"
#include "MoCoBus/omnetwork.h"
#include "Slim/commandhistorymodel.h"
#include "Slim/slimcommandparser.h"

namespace Ui {
class SlimWindow;
}

class SlimWindow : public QWidget
{
Q_OBJECT

public:
SlimWindow(OMNetwork* net, CommandHistoryModel* hist, SlimCommandParser* parse, QWidget *parent = 0);
~SlimWindow();

private slots:
void onCmdEntry();
void onCmdResult(slimCommand);

public slots:
void registerNewDevice(OMbusInfo* p_bus, OMdeviceInfo* p_dev);
void removeDevice(OMbusInfo* p_bus, unsigned short p_addr);
private:

Ui::SlimWindow *ui;
CommandHistoryModel* _cmdHist;
OMNetwork* _net;
SlimCommandParser * _parser;
};


#endif // SLIMWINDOW_H


slimwindow.cpp (just up to, and including, the constructor) :



#include "slimwindow.h"
#include "ui_slimwindow.h"


#include <QDebug>
#include <QtEndian>

#include "Core/ErrorDialog/errordialog.h"


SlimWindow::SlimWindow(OMNetwork* net, CommandHistoryModel* hist, SlimCommandParser* parse, QWidget *parent) :
QWidget(parent),
ui(new Ui::SlimWindow)
{

ui->setupUi(this);

_parser = parse;
_net = net;
_cmdHist = hist;

ui->historyTableView->setModel(_cmdHist);

QObject::connect(_cmdHist, SIGNAL(commandResults(slimCommand)), this, SLOT(onCmdResult(slimCommand)), Qt::QueuedConnection);


}

ChrisW67
14th June 2012, 02:59
Any chance of posting the *.ui file, since it is the only one that matters when it comes to generating the ui_*h file. Generally you get non-Qt includes only when you use the Promotion mechanism in the UI design.

droneone
14th June 2012, 03:28
I think you hit the nail on the head there... I see now what's different about this one, namely:



<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SlimWindow</class>
<widget class="SlimWindow" name="SlimWindow">


I see also that it does show as promoted in the Designer UI. Is there a way, short of editing the ui file outside of Qt Creator to un-promote this widget? The docs indicate there should be a "Demote to" context option, which does not appear when I right-click on the widget?

(Edit was because I had some issues with quick reply timing out, removed bad replies)

ChrisW67
14th June 2012, 06:06
AFAICT Designer does not allow you to promote the top-most widget in the design in the first place. How did you get to this point?

You should be able to make line 4 read:


<widget class="QWidget" name="SlimWindow">

but there will be other elements in the <customwidgets> part of the file related to the "promoted" widget including what headers to include.

Another approach would be to copy and paste this design's content into a new one.

droneone
14th June 2012, 14:49
AFAICT Designer does not allow you to promote the top-most widget in the design in the first place. How did you get to this point?

You should be able to make line 4 read:


<widget class="QWidget" name="SlimWindow">

but there will be other elements in the <customwidgets> part of the file related to the "promoted" widget including what headers to include.

Another approach would be to copy and paste this design's content into a new one.

Chris,

Thanks for your help - now, as to how it got this way? That's a good question - but I see that designer does not seem to prevent me from promoting a top-level widget in a form, I just have to type in the name, and it seems to do it. After manually removing all of the promoted content, I finally found how to demote a widget via designer (even though everything is removed from that ui file, I'm guessing the .pro.user retains some information). You right-click any widget, select "promoted widgets", then click on the one you want to get rid of, and a '-' icon appears now. Wish I had noticed that last night =)

FYI, in addition to changing the class of the widget, one would also want to look for xml like:



<customwidgets>
<customwidget>
<class>SlimWindow</class>
<extends>QWidget</extends>
<header>slimwindow.h</header>
<container>1</container>
</customwidget>
</customwidgets>


Thanks again!

wysota
14th June 2012, 15:23
but I see that designer does not seem to prevent me from promoting a top-level widget in a form
My Designer does not allow me to do so. Of course provided we all understand the term "top level widget" the same way. I'm talking about right clicking a blank form and looking for "Promote to..." menu entry which is not there.

droneone
14th June 2012, 15:45
My Designer does not allow me to do so. Of course provided we all understand the term "top level widget" the same way. I'm talking about right clicking a blank form and looking for "Promote to..." menu entry which is not there.

Ahh, I am using the designer inside of Creator 2.4.1, and it doesn't have a 'promote to', as far as I can see when right-clicking a blank form - but instead, when I click on any widget on the right (in the list of widgets, including the top-level one), it has a "Promoted Widgets" option, which once opened, allows one to manually define a new promoted class by simply choosing the base class, typing the promoted class name, and specifying the header file. This appears to be the same dialog I get when I click "promote to" on any widget included in a form.

wysota
14th June 2012, 15:48
Ahh, I am using the designer inside of Creator 2.4.1, and it doesn't have a 'promote to', as far as I can see when right-clicking a blank form - but instead, when I click on any widget on the right (in the list of widgets, including the top-level one), it has a "Promoted Widgets" option, which once opened, allows one to manually define a new promoted class by simply choosing the base class, typing the promoted class name, and specifying the header file. This appears to be the same dialog I get when I click "promote to" on any widget included in a form.

This dialog does not allow you to PROMOTE the top-level widget, only provides a way to define mappings for promotions (the "Promote" button is greyed out).