I'm working on a project using QT. To link it with premake, I cloned the addon which generate a QT solution premake-qt. It works fine when it comes to use qt in general.
But I need to create custom signals so to do that, I had to add Q_OBJECT in my header file.
Here is the file:
#pragma once
#ifndef _WINDOW_H_
#define _WINDOW_H_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QProgressBar>
#include <QSlider>
#include <QFileDialog>
#include <QtDebug>
#include <QFile>
#include <QTextStream>
#include <QMenu>
class WindowUI : public QWidget
{
Q_OBJECT
enum class State {
Save = 0,
Export = 1,
};
... // rest of header
So without the Q_OBJECT everything works fine, but when I build with it, I have an error.
>Moc'ing Window.h
>the specified path cannot be found.
And something I found is that it generates a moc_Window.args and a moc_Window.cpp in the vscode tree but the .cpp is not in my work directory.
If needed I can provide my premake.lua config file where I link QT if something is missing.
Do I have to run qmake on my project when I add Q_OBJECT ?
Try removing the class from VS project and adding it back. I've had similar issues when changing a normal class to QObject based (including Q_OBJECT macro). I think the issue is related to how the Qt VS add-in does the moc'cing.
Related
I need to transition from qmake to CMake for a large C++ project, but while working through a toy example I encountered some behavior that I don't understand. The example code features a single header file, and when that header file is moved into a subdirectory, I get a missing vtable error for the MainWindow class.
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(HelloCMake)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("include")
set(INCLUDES include/mainwindow.h)
set(SOURCES
main.cpp
mainwindow.cpp
mainwindow.ui
)
add_executable(hello-cmake ${SOURCES}) # error
# add_executable(hello-cmake ${SOURCES} ${INCLUDES}) # no error
target_link_libraries(hello-cmake Qt5::Widgets)
include/mainwindow.h (boilerplate)
#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
mainwindow.cpp (boilerplate)
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow() {
delete ui;
}
main.cpp (boilerplate)
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Here's what I see when I run make (after first running cmake .):
[ 20%] Automatic MOC and UIC for target hello-cmake
[ 20%] Built target hello-cmake_autogen
[ 40%] Linking CXX executable hello-cmake
Undefined symbols for architecture x86_64:
"vtable for MainWindow", referenced from:
MainWindow::MainWindow(QWidget*) in mainwindow.cpp.o
MainWindow::~MainWindow() in mainwindow.cpp.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [hello-cmake] Error 1
make[1]: *** [CMakeFiles/hello-cmake.dir/all] Error 2
make: *** [all] Error 2
If I add the header to the target by swapping the second add_executable command for the first one in CMakeLists.txt, the error goes away. I can also make the error go away by moving the header into the base directory with the .cpp files. However, I'd like to know what's actually going on here. I understand the general value of including the header files in the target, but why is a missing vtable error generated when I don't do this? Unless I grossly misunderstand, all the contents of mainwindow.h should be available while mainwindow.cpp is being compiled by virtue of the #include, whether or not the header is part of the add_executable statement.
--
EDIT
Here are the contents of ui_mainwindow.h, in case they're somehow relevant.
/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created by: Qt User Interface Compiler version 5.10.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_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/QToolBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QWidget *centralWidget;
QPushButton *pushButton;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QStringLiteral("MainWindow"));
MainWindow->resize(393, 307);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
pushButton = new QPushButton(centralWidget);
pushButton->setObjectName(QStringLiteral("pushButton"));
pushButton->setGeometry(QRect(10, 10, 113, 32));
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 393, 22));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QStringLiteral("statusBar"));
MainWindow->setStatusBar(statusBar);
retranslateUi(MainWindow);
QObject::connect(pushButton, SIGNAL(released()), pushButton, SLOT(hide()));
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr));
pushButton->setText(QApplication::translate("MainWindow", "Do not press", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
I was able to migrate my real project to CMake with exactly one hiccup: the linker wasn't happy with any of the signal functions in my QObject-derived classes. (For those not familiar with Qt, a meta-object compiler, moc, magically converts certain empty functions marked as signals in a header file into real functions that the C++ compiler can use.) My conclusion is that both problems resulted from CMake not seeing the header files for a QObject-derived class, and so they were not sent to the moc in spite of the CMAKE_AUTOMOC setting.
The upshot is, if moc (or uic or rcc) needs to compile a file, then CMake has to know it exists before building any dependent targets. The crude solution I used for my project was to grep Q_OBJECT in the directory with all my header files, and copy/paste this list into a long set command in CMakeLists.txt
set(MOC_SOURCES
include/applewidget.h
include/borangewidget.h
...
)
and then add ${MOC_SOURCES} to my add_executable line. There may be a more sophisticated solution that involves building these objects separately, but my use of CMake has not yet reached that level of sophistication.
Meta object compiler (moc) generates moc_*.cpp files from headers. So the build system needs to know which headers to feed it. Similar to C++ compiler that needs to know which files to process. So when working with CMake and Qt you need to consider the header files as source files. CMake is smart enough to not ask C++ compiler to compile them so there's no harm in adding them for other libraries too.
Unfortunately neither Qt-CMake nor CMake-Qt documentation state this explicitly but you should always add headers to the list of sources in add_executable/add_library for CMAKE_AUTOMOC to work.
Another important thing is the minimal required version of CMake. CMake 2.6 does not support Qt5. Neither does CMake 2.8. The official Qt documentation claims the minimal CMake version to be 3.1.0. However CMake 3.0 already has Qt5 support. Still those version are way too old, slow, and buggy so consider updating the requirement. I'd recommend 3.11 or latest stable.
I've installed Qt5.12.1 and trying to open a working project but its giving me errors. I dont have experience with Qt neither C++ but I need to fix some bugs in this project. It gives lots of errors like this and I'm using Qt Creator because I dont have access to internet from my work computer.
Code where it gives error goes like this:
#include "chartview.h"
#include <QMouseEvent>
#include <qdebug.h>
#include <QtCharts/qxyseries.h>
#include "configvalues.h"
#include "qmath.h"
ChartView::ChartView(QChart *chart , QWidget *parent):
QChartView(chart,parent), m_isTouching(false), delta(20) {
int rubberBand = ConfigValues::instance()->settings->value(Chart/"RubberBand").toInt();
QColor c1 = ConfigValues::instance()->settings->value("Chart/TooltipColor").value<QColor>();
setRubberBand((QChartView::RubberBands) rubberBand);
In this code, QChart and QWidget gives error and because of them so does ChartView. Why I'm having these errors?
Edit:
In ChartView.h file
#ifndef CHARTVIEW_H
#define CHARTVIEW_H
#include <QchartView>
#include <qrubberband.h>
#include <QDateTime>
exist. But only QDateTime is not giving any error. Others giving "file not found"
hmmmm hi
it'd be much more easier if you would offer an error log also.
but as much as I know these errors are due to the compiler that cannot find the packages mentioned when compiling.
if you have the errors like unknown type : QWidget, QChart, QEvent it probably will be fixed if you import the packages of QtCore and QtCharts to the project and that will be done like this:
go to project qmake file like : project.pro
add these lines to it:
QT += core widgets charts
I have installed Qt Creator with the msvc2017_64 binary. I also installed the Qt add-in for VS2017. I can create a QtGuiApplication without any problems, but when i try to compile it, many errors appear. I listed them here, on pastebin, because I cannot add this many characters to Stackoverflow. I'm sorry for that.
Do I need any essential packages for this? I installed C++ for VS2017 ofc. I also included the QtPath in the Qt VS Tools menu.
I did not edit the files since project creation and compiling fails due to errors.
EDIT: This problem is solved here. But not only the Errors form Pastebin exist, also the one following in the QtGuiApplication.h
QtGuiApplication.h: (Errors marked as comments)
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication1.h" //This could not be found
class QtGuiApplication1 : public QMainWindow
{
Q_OBJECT
public:
QtGuiApplication1(QWidget *parent = Q_NULLPTR);
private:
Ui::QtGuiApplication1Class ui; //Ui namespace does not exist
};
QtApplication.cpp:
#include "stdafx.h"
#include "QtGuiApplication1.h"
QtGuiApplication1::QtGuiApplication1(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
main.cpp:
#include "stdafx.h"
#include "QtGuiApplication1.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QtGuiApplication1 w;
w.show();
return a.exec();
}
I solved this problem myself!
The Qt add-in creates the Project with the Windowns 8.1 SDK, you need to retarget it to the Win 10 SDK to get the compile Errors from the QtGuiApplication.h away. Even if the 8.1 SDK is installed. Seems like a bug.
The solution was quite simple to me, just unload and then reload the solution from Solution Explorer!
This will clear all c++ compiler errors! Don't know why ...
I created app for building graphics. Just press button, choose file and look to the canvas for visualisation.
I used QGraphicsView for drawing. App works perfectly in debug mode. But when I'm deploying it with AppImage it doesn't work. I press button, choose file and nothing happens. I have no any message or warning.
I didn't use qml. My app is very simple.
List of headers, that I've include:
#include <QApplication>
#include <QMainWindow>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QHBoxLayout>
#include <QMetaType>
#include <QThread>
look of my release dir:enter image description here
Any help will be appreciated
I am running QtCreator in OSX Lion, and anytime I create a class that requires the Q_OBJECT macro, I get an error when I try to build my application. The code for that class is below, as is the error I am recieving. Any clue what may be going on?
Note: I have already tried cleaning, running qmake and re-building to no avail.
#ifndef TASKLIST_H
#define TASKLIST_H
#include <QObject>
class TaskList : public QObject
{
Q_OBJECT
public:
explicit TaskList(QObject *parent = 0 );
public slots:
void addTask();
void displayTasks();
};
#endif // TASKLIST_H
And the error:
:-1: error: symbol(s) not found for architecture x86_64
:-1: error: collect2: ld returned 1 exit status
There still seems to be a bug in Qt Creator.
I have a large project with a number of classes all having Q_OBJECT and another number of classes not having Q_OBJECT. It works fine. However, if I add Q_OBJECT to one of the classes which didn't have it, I get this "collect2: ld returned 1 exit status" error when trying to build it.
Checking the build directory, I see that the moc file for this class is missing. Qt just does not create the moc files for it! However, if I remove the header and cpp files from the project and add them again, it works, the moc files are generated and the project is built successfully.
This problem seems to happen only if I have a class which did not have Q_OBJECT and it was built succesfully in the past. A fresh class with Q_OBJECT that was never compiled before adding "Q_OBJECT" always works fine.
So, if this problem happens and you are sure you included everything correctly (and commenting out Q_OBJECT lets the project to be built correctly), do the following:
remove the .h and .cpp files (where you just added the Q_OBJECT) from the project.
add them to the project again
clean project
build it again.
EDIT
In some cases running qmake (Build/Run qmake) followed by a Clean All is enough.
tasklist.h file
#ifndef TASKLIST_H
#define TASKLIST_H
#include <QObject>
class TaskList : public QObject
{
Q_OBJECT
public:
explicit TaskList(QObject *parent = 0 );
public slots:
void addTask(){};
void displayTasks(){};
};
#endif // TASKLIST_H
tasklist.cpp
#include "tasklist.h"
TaskList::TaskList(QObject *parent) :
QObject(parent)
{
}
main.cpp
#include <QtCore/QCoreApplication>
#include "tasklist.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TaskList t;
return a.exec();
}
works fine, but it should be in separate files