I try to include header window into his child window. Let see a code:
//header of main window
#include "second_window.h" // include child window
class mainclass : public QMainWindow
{
Q_OBJECT
public:
mainclass(QWidget *parent = 0);
~mainclass();
second_window *h_secondwindow = nullptr;
private:
Ui::mainclass ui;
};
And Second
//header second_window.h
#include "mainwindow.h" // only this from mainwindow class
class second_window : public QWidget
{
Q_OBJECT
public:
third_window * h_third_window = nullptr;
second_window(QWidget *parent = 0);
~second_window();
private:
void reDrawTable();
Ui::second_window ui;
};
#endif // second_window_H
And when in "second_window.h" i try to include "header of main window" (lets call it mainwindow.h )
I got error by this line (in main window) :
second_window *h_secondwindow = nullptr;
Errors like:
//qdatetime.h ( i dont edit this file ;0 )
error C2059: syntax error : '::'
static inline qint64 nullJd() { return std::numeric_limits<qint64>::min(); }
//mainwindow.h
error C2143: syntax error : missing ';' before '*'
second_window *h_secondwindow = nullptr;
I need this variable bcoz i have to operate in main window method on this child window.
Any idea?
Try, cross checking your "second_window.h" to see if there any code errors, it might be there are some few errors. Such errors mainly happen with pointers and references, so an error might be possible!
You shouldn't include the header files inside each other. You can use a forward declaration of mainwindow class in second_window.h :
//header second_window.h
class mainwindow;
Forward declarations mean that you can only use that class as a pointer in the header file and not a class instance. So using this way you can now have a pointer to your mainwindow in second_window.h.
But it is recommended to check if you can change your design and eliminate this circular dependency.
I think your code is dark means.
Why does second_window include main_window?
You should init in main window.h:
second_window* _secondWindowUi;
in .cpp file :
_secondWindowUI = new second_window();
It is easy!
Related
Is it possible that moc gathers classes with Q_OBJECT macro both from a header and corresponding cpp file and merges the results?
For example, in MyWidget.hpp:
class MyWidget : public QWidget
{
Q_OBJECT
//...
//signals and slots...
};
and in MyWidget.cpp:
class AuxLabel : public QLabel
{
Q_OBJECT
//....
//signals and slots
};
#include MyWidget.moc
Currently I get a strange error at run time, something similar to:
symbol lookup error: /....so: undefined symbol: _ZTVN4AuxLabelE
I am trying to write an application where I would have a generic dialog window and specific dialog windows that would inherit some basic functionalities from the generic one. I am not sure this is the best approach for this, but this is how I did it (The CGenericProject class was created from Dialog template in Qt Creator):
CGenericProject.h:
#include <QDialog>
namespace Ui {
class CGenericProject;
}
class CGenericProject : public QDialog
{
Q_OBJECT
public:
explicit CGenericProject(QWidget *parent = 0);
~CGenericProject();
protected:
Ui::CGenericProject *ui;
};
CGenericProject.cpp:
#include "cgenericproject.h"
#include "ui_cgenericproject.h"
CGenericProject::CGenericProject(QWidget *parent) :
QDialog(parent),
ui(new Ui::CGenericProject)
{
ui->setupUi(this);
}
CGenericProject::~CGenericProject()
{
delete ui;
}
CEisProject.h:
#include "cgenericproject.h"
class CEisProject : public CGenericProject
{
public:
CEisProject();
~CEisProject();
};
CEisProject.cpp:
#include "ceisproject.h"
CEisProject::CEisProject()
{
ui-> NO ACCESS
}
CEisProject::~CEisProject()
{
}
As you see in the CEisProject.cpp file, I have no access to the ui field inherited from CGenericProject, even though it is protected. I mean, I see ui itself, but I dont see its methods and members. Any other variable that I would define there, would be accessible. What's wrong? I would appreciate all help in this manner.
You have to add the line
#include "ui_cgenericproject.h"
to the CEisProject.cpp file.
The CGenericProject.h file is included in CEisProject.h, but CEisProject.h does not have access to CGenericProject.cpp. In the header of your base class you have a only forward declaration of Ui::CGenericProject, and you include its file in the .cpp. So CGenericProject.cpp knows the implementation of this class.
But CEisProject.cpp doesn't have access to that, so you have to include the file again in here.
NOTE
Your forward declaration is confusing, you should indent it properly. Also, add some comments to your code to add some clarity for who is reading it, you're using two different classes with the same name.
This is about a Qt 5.3.2 project buildt using CMake.
I have designed a QMainWindow using the Qt Designer, leading
to main.ui.
CMakeLists.txt (the almost complete thing may be
found here where I already posted it for a different question:
Linking and UIC order in a CMake Qt project )
already takes care of calling UIC so I have my hands on ui_main.h.
ui_main.h offers the class Ui::MainWindow with the plain form information
where all the buttons and stuff should be and the method *void setupUi(QMainWindow MainWindow).
Now my workflow (is it even a feasible one?) goes like this:
I build a totally new header file Form_main.h:
// Form_main.h
[..]
class Form_main : public MainWindow, public QMainWindow
{
Q_OBJECT
privat slots:
void on_some_event();
[..]
};
The class uses said auto-generated MainWindow::setupUi(this) to 'get in shape' and QMainWindow to be, well, a QMainWindow with all that stands for.
But now I am in a dilemma: Either I remove the Q_OBJECT macro call leading to connect(..) no longer recognizing that Form_main has signal slots, or
I keep the Q_OBJECT leading to the infamous
undefined reference to `vtable for display::Form_main'
error while linking the project.
Now, there have been, in fact, people with similar issues.
Naming some links:
http://michael-stengel.com/blog/?p=103
Qt Linker Error: "undefined reference to vtable"
Undefined reference to vtable... Q_OBJECT macro
Qt vtable error
A hint I got from the last one: "MOC must generate code for ui_main.h and the generated code must be compiled and linked."
In any case, these answers all seem to boil down to 'running qmake again'. Well, I use CMake all the way wanting my project to configure and compile after exactly
cmake .
make
What I did try was deleting everything in and below the build directory
(including every auto-generated file) and then running cmake . && make;.
Sadly that did not help. I am afraid this is my second noob question today... would you bear with me once more?
=== AFTER TRYING GREENWAYS ANSWER I PROVIDE MORE DETAILS. ===
Here is the autogenerated ui_main.h
/********************************************************************************
** Form generated from reading UI file 'main.ui'
**
** Created by: Qt User Interface Compiler version 5.3.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAIN_H
#define UI_MAIN_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
[.. more Widget Includes ..]
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QAction *action_exit;
[.. more sub widgets like that .. ]
void setupUi(QMainWindow *MainWindow)
{
[ .. Setting up the form. Harmless code. .. ]
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
[ .. completely harmless .. ]
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAIN_H
Reading all this and incorporating your post right now I am at
// form_main.h
#ifndef MHK_FORM_MAIN_H
#define MHK_FORM_MAIN_H
#include <QMainWindow>
#include "ui_main.h"
[..]
namespace Ui { class MainWindow; }
namespace display
{
class Form_main : public QMainWindow
{
Q_OBJECT
private:
ostream* stdout;
ostream* stderr;
Ui::MainWindow* uiMainWindow;
/** Called by the constructor. Sets up event connections and other
* preliminary stuff the qt Designer is overtasked with. */
void setup_form();
[..]
public:
explicit Form_main(QWidget* parent = 0);
~Form_main();
private slots:
void exit_program();
};
}
#endif
And my cpp
// form_main.cpp
#include "ui_main.h"
#include "form_main.h"
[..]
using namespace Ui;
namespace display
{
void Form_main::setup_form()
{
QObject::connect(uiMainWindow->action_exit, SIGNAL(triggered()), this, SLOT(exit_program()));
[..]
}
Form_main::Form_main(QWidget* parent) : QMainWindow(parent)
{
uiMainWindow = new Ui::MainWindow();
uiMainWindow->setupUi(this);
[..]
#if defined(Q_OS_SYMBIAN)
this->showMaximized();
#else
this->show();
#endif
}
Form_main::~Form_main()
{
delete uiMainWindow;
}
[..]
Form_main::exit_program()
{
this->close();
(*stdout) << "Thanks for playing " << getProgramName() << endl;
}
}
Ok. I see (partly) the problem. Just create a widget class like this:
.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
This is how the QtCreator creates ui-Widgets. "ui_MainWindow.h" is your generated .h file.
Thanks for all your help! However, the problem was in CMakeLists.txt after all. The comment of Chris Morlier on Undefined reference to vtable pointed me to the solution.
The pertinent passage goes:
For Qt users: you can get this same error if you forget to moc a header
I simply had to add the header form_main.h into this line:
QT5_WRAP_CPP(qt_H_MOC ${qt_H} "${DIR_SRC}/include/form_main.h")
I'm modifying a Qt example 'collidingmice' which comes with the Qt code.
In the original source, the QApplication contains QView and QScene, but I made a class CollidingMice containing the QView and QScene to kill the view and scene using keyboard input. I want to send the keyboard input to CollidingMice class.
I read 4 or 5 questions in stack overflow about 'undefined reference to vtable for..' but could not find the case that fits me. I checked that
1. there is no virtual function in the parent classes that is not defined.
2. I tried adding definition of destructor ~CollidingMices() {}
3. and I'm 99% sure there is no undefined member function in the CollidingMice code below.
#include "mouse.h"
#include <QtGui>
#include <math.h>
static const int MouseCount = 7;
class CollidingMice : public QMainWindow
{
Q_OBJECT
private:
QGraphicsView *view;
QGraphicsScene scene;
QTimer *timer;
public:
CollidingMice(QWidget *parent = 0): QMainWindow(parent) {
scene.setSceneRect(-300, -300, 600, 600);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
for (int i = 0; i < MouseCount; ++i) {
Mouse *mouse = new Mouse;
mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
::cos((i * 6.28) / MouseCount) * 200);
scene.addItem(mouse);
}
view = new QGraphicsView(this);
view->setRenderHint(QPainter::Antialiasing);
view->setBackgroundBrush(QPixmap(":/images/cheese.jpg"));
view->setCacheMode(QGraphicsView::CacheBackground);
view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
view->setDragMode(QGraphicsView::ScrollHandDrag);
view->setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) || defined(Q_WS_SIMULATOR)
view->showMaximized();
#else
view->resize(600, 450);
view->move(30,30);
view->show();
#endif
timer = new QTimer;
QObject::connect(timer, SIGNAL(timeout()), &scene, SLOT(advance()));
timer->start(1000 / 33);
}
private:
void keyPressEvent(QKeyEvent *event);
};
void CollidingMice::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_q) {
close();
}
}
int collidingmice_main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
CollidingMice w;
return app.exec();
}
ADD and EDIT : After deleting the QOBJECT above as svlasov told me to, and after fixing the constructor as below (see the setScene..my colleage suggested me.)
view = new QGraphicsView(this);
view->resize(600,500);
view->setScene(&scene);
view->setRenderHint(QPainter::Antialiasing);
I could compile it and execute it.
If you use Q_OBJECT in class definition you have to extract the class into separate header file.
If you don't declare signals and slots in CollidingMice class, just remove Q_OBJECT and it will compile.
UPDATE
As #KubaOber commented, you can simply include to the end of your file.cpp file:
#include "file.moc"
and qmake will do all the job.
It seems your class is declared in .cpp rather than .h
Qt MOC doesn't like it. You may add #include "mysrcfile_moc.cpp" at the end of the file or move the class declaration to mysrcfile.h Don't forget to clean & rebuild after that.
There are 3 issues with your code...
Qt parses the class header and constructs underlying functions related to QObject hierarchy, including symbols for export. This is a rudimentary parser and needs an explicit header file - both for ease of parsing and for symbol export. Create a header - trust me, it's 5 seconds of work to create a file, cut-paste the class declaration and include it back... and saves a lot of time troubleshooting Qt compile issues.
the scene has a scene rectangle, but the view is a regular QWidget - which means the Window should use a layout class and include it in like other QWidgets. Failing this, the view will be sized to something like QSize(1,1) and located at pos(0, 0) by default. This is why you can't see it.
For the QGraphicsScene, you're looking for the slot update() and not advance()
I am getting a mysterious error trying to subclass QTreeWidget. Below is code from the relevant files. In QtDesigner, I have promoted a QTreeWidget to a treeWidget, but I get the following error:
Error 1 error C2061: syntax error : identifier 'treeWidget' Visual Studio 2010\Projects\hw2\QTOpenGL\GeneratedFiles\ui_opengldemo.h 72 1 QTOpenGL
I have been told not to edit code in the ui_ files, so I'm assuming this problem can be solved without going in there. Any ideas? Does the code below give enough information to solve this issue? Thanks.
**treeWidget.h:**
#ifndef TREEWIDGET
#define TREEWIDGET
#include <QTreeWidget>
#include "gNode.h"
class treeWidget :
public QTreeWidget
{
Q_OBJECT
public:
treeWidget(QWidget*);
~treeWidget(void);
public slots:
void topLevelItem(gNode* node);
};
#endif
**treeWidget.cpp**
#include "treeWidget.h"
treeWidget::treeWidget(QWidget* parent) : QTreeWidget(parent)
{
}
treeWidget::~treeWidget(void)
{
}
void treeWidget::topLevelItem(gNode* node){
addTopLevelItem(node);
}
Figured it out. Changed name to myTreeWidget from treeWidget and all works fine.