Reputation: 4627
I'm new in Qt and trying to do a text editor example from Qt 5. But, I'm doing that without QtCreator. Of course I have QtCreator installed, I just want to try doing that example without QtCreator. My steps in doing this are:
Write main.cpp
, notepad.cpp
and notepad.h
exactly like in the
example. (Except for include
preprocessor, I write the complete
path like:
#include <qt/QtWidgets/QMainWindow>
not just:
#include <QMainWindow>
Create notepad.ui
file with QtDesigner.
ui_notepad.h
file with uic-qt5 notepad.ui > ui_notepad.h
command.notepad.pro
file with qmake-qt5 -project
command.Add these lines in notepad.pro
file:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
Generate Makefile
with qmake
command.
make
command.Those step is what I can understand on how QtCreator doing the task automatically. And then, make
complaints about incomplete type and forward declaration. But, If I'm doing this with QtCreator, the project is compiled just fine.
What did I miss there?
These are the error messages that I get:
notepad.cpp: In constructor ‘Notepad::Notepad(QWidget*)’:
notepad.cpp:4:72: error: invalid use of incomplete type ‘class Ui::Notepad’
Notepad::Notepad (QWidget* parent) : QMainWindow (parent), ui (new Ui::Notepad) {
^
In file included from notepad.cpp:1:0:
notepad.h:4:8: error: forward declaration of ‘class Ui::Notepad’
class Notepad;
^
notepad.cpp:5:4: error: invalid use of incomplete type ‘class Ui::Notepad’
ui->setupUi (this);
^
In file included from notepad.cpp:1:0:
notepad.h:4:8: error: forward declaration of ‘class Ui::Notepad’
class Notepad;
^
notepad.cpp: In destructor ‘virtual Notepad::~Notepad()’:
notepad.cpp:9:9: warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]
delete ui;
^
notepad.cpp:9:9: warning: invalid use of incomplete type ‘class Ui::Notepad’
In file included from notepad.cpp:1:0:
notepad.h:4:8: warning: forward declaration of ‘class Ui::Notepad’
class Notepad;
^
notepad.cpp:9:9: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
delete ui;
^
Makefile:660: recipe for target 'notepad.o' failed
make: *** [notepad.o] Error 1
Update
ui_notepad.h file:
/********************************************************************************
** Form generated from reading UI file 'notepad.ui'
**
** Created by: Qt User Interface Compiler version 5.4.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_NOTEPAD_H
#define UI_NOTEPAD_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralwidget;
QVBoxLayout *verticalLayout_2;
QVBoxLayout *verticalLayout;
QTextEdit *textEdit;
QPushButton *quitButton;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(800, 600);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QStringLiteral("centralwidget"));
verticalLayout_2 = new QVBoxLayout(centralwidget);
verticalLayout_2->setObjectName(QStringLiteral("verticalLayout_2"));
verticalLayout = new QVBoxLayout();
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
textEdit = new QTextEdit(centralwidget);
textEdit->setObjectName(QStringLiteral("textEdit"));
verticalLayout->addWidget(textEdit);
quitButton = new QPushButton(centralwidget);
quitButton->setObjectName(QStringLiteral("quitButton"));
verticalLayout->addWidget(quitButton);
verticalLayout_2->addLayout(verticalLayout);
MainWindow->setCentralWidget(centralwidget);
textEdit->raise();
quitButton->raise();
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QStringLiteral("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 27));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QStringLiteral("statusbar"));
MainWindow->setStatusBar(statusbar);
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0));
quitButton->setText(QApplication::translate("MainWindow", "Quit", 0));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_NOTEPAD_H
notepad.ui file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="textEdit"/>
</item>
<item>
<widget class="QPushButton" name="quitButton">
<property name="text">
<string>Quit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<zorder>textEdit</zorder>
<zorder>quitButton</zorder>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>27</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Upvotes: 1
Views: 369
Reputation:
Classes namespaced in Ui::
are automatically generated by the Qt UIC metacompiler after compiling .ui
files. Your code expects Ui::Notepad
to be generated and automatically linked into the project with qmake/uic.
After looking at the XML of the .ui
file that QtDesigner creates, you can see the following line:
<class>MainWindow</class>
That means that the class Ui::MainWindow
is generated. If you wanted to generate Ui::Notepad
instead, open the .ui
form in QtDesigner and rename the top level widget from MainWindow
to Notepad
. Then Ui::Notepad
would appear in your project.
It would cause the XML to look like <class>Notepad</class>
which would make Ui::Notepad
available in your code
Upvotes: 1