Qt 5.5 QOpenGLWidget link error not linking any openGL calls - c++

I tried to build a simple OpenGL App with Qt 5.5.1, and everything is fine up until I try to use openGL native function calls like glClearColor.
The Widget actually compiles and produces a black screen, but after I try to use any openGL native function it doesn't even link, but produces the error:
glwidget.cpp:10: error: undefined reference to '_imp__glClearColor#16'
Here is the .pro file:
QT += core gui opengl
CONFIG += windows
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Vehicle_simulation
TEMPLATE = app
SOURCES += main.cpp\
simulation.cpp \
glwidget.cpp
HEADERS += simulation.h \
glwidget.h
FORMS += simulation.ui
I'm using Desktop Qt mingw492_32 kit.
The strange thing though is that I did not find libQtOpenGL.so in the lib folder. Is my QT installation faulty? I tried to reinstall it multiple times, but it didn't help. Where can I download that specific library?
linking it to the project would solve the problem, but I can't seem to find it anywhere.
The problem is the openGL module is missing from the QT installation, it's not that I am unable to link to it.

After I opened up an example program by chance, just to take a look at the implementation; I found that the same QOpenGLWidget has been implemented in a new example program.
After a bit of analysis I managed to figure out the problem.
QT has an internal openGL implementation and native openGL support as well. The widget I used inherited from QOpenGLWidget, but the openGL function calls (like glClearColor) tried to access native openGL implementation in Qt. which Since those were not included in my Qt build, the project would not build.
To fix this one has to either run a custom Qt core build, or use the openGL wrapper provided by Qt.
I used the Qt wrapper in the end, which was also used by the example program Cube. the class used to implement the widget (called GLWidget in my implementation) has to inherit not only from QOpenGLWidget, but also from QOpenGLFunctions. The latter part was missing from my implementation. The source code for it is the following:
glwidget.h (initial):
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
class GLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent);
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
};
#endif // GLWIDGET_H
glwidget.h (fixed):
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent);
protected:
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
};
#endif // GLWIDGET_H
Be careful!
Before any gl* functions are used the function initializeOpenGLFunctions(); has to be called, otherwise a very cryptic run-time error will pop up.
i.e.:
void GLWidget::initializeGL(){
initializeOpenGLFunctions();
glClearColor(1,0,0,1);
}
Hope this will help someone else as well.

Related

The program has unexpectedly finished in QT opencv

I know that this has been posted many times,but I could not find the solution from previous posts. I followed tutorial on How to setup Qt and openCV on Windows from wiki Qt.
My .pro file and mainwindows.cpp are shown below. I wanted to open image following the example. What is wrong here? Checked the opencv version and it is the same as libs included. The PATH is also correct.
The cpp file
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
cv::Mat image = cv::imread("C://1.jpg", 1);
cv::namedWindow("My Image");
cv::imshow("My Image", image);
}
MainWindow::~MainWindow()
{
delete ui;
}
and
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opencvtest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:\opencv\build\include
LIBS += C:\opencv-build\bin\libopencv_core451.dll
LIBS += C:\opencv-build\bin\libopencv_highgui451.dll
LIBS += C:\opencv-build\bin\libopencv_imgcodecs451.dll
LIBS += C:\opencv-build\bin\libopencv_imgproc451.dll
LIBS += C:\opencv-build\bin\libopencv_features2d451.dll
LIBS += C:\opencv-build\bin\libopencv_calib3d451.dll
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
When program crashes like that under Qt Creator, and you have extra libraries, the very likely reason is that the extra libraries are missing from the runtime PATH.
In this case, you need to add C:\opencv-build\bin to the PATH. There are at least 3 ways to go about it.
Edit the system environment, so that the relevant directory is always in the system PATH. You need to restart Qt Creator for this change to take effect. This is not the recommended way, unless you actually want these things in there also for other purposes.
You can edit the Build environment of the project under Qt Creator Project view. There's separate configuration for each build type, so you may need to do this to them all separately, which both good and bad. It is good, because then you can have different directory for different builds (for example debug vs relase, MSVC vs MinGW builds). It's bad because it's extra hassle and makes it easier to have something wrong.
You can add it to the run environment in the Qt Creator Project view. Then it will be the same for all build types.
In this case, 3 is probably the way to go.
Qt Creator annoyingly does not display any information about which DLL is missing, it just says the program crashed. This can be solved by instead string the "Qt command prompt" for the correct toolchain from Windows Start menu (search Qt and you should find it). Then go to the built .exe directory and run the .exe. You should now get an error dialog where Windows tells you which DLL it failed to find. Then you can look where that DLL is and add it to the path and try again, until the program starts. After you know the directories using this method, you can then add them to Qt Creator as explained above.

Using signals in Qt breaks DLL

I'm running a simulation program in Visual Studio 2013 for which I wanted a simple GUI to output/input data.
Since I know some Qt I decided to write a small Qt5 program in Qt Creator, build it as a .dll and link this .dll in my program. The program then calls an initialization function to start the GUI.
Overall this works quite well. The GUI works just like a stand-alone Qt program would. However, once I added a custom signal to my Qt .dll like this:
//File.h
class MainGui : public QMainWindow
{
Q_OBJECT
public:
explicit MainGui(QWidget *parent = 0);
~MainGui();
signals:
void addItemSignal(QGraphicsView* it);
private slots:
void addItemImpl(QGraphicsView* it);
private:
Ui::MainGui *ui;
};
//File.cpp
void MainGui::addItemImpl(QGraphicsView *it)
{
//do anything
}
MainGui::MainGui(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainGui)
{
QObject::connect(this, &MainGui::addItemSignal,
this, &MainGui::addItemImpl);
}
MainGui::~MainGui()
{
delete ui;
}
I ended up getting the following error message when trying to start my main program:
The procedure entry point could not be located in the dynamic link library e:\...\...\MyQtLibrary.dll.
The two spaces between "point" and "could" are not a mistake - it seems like, for some reason, the entry point is not set to anything at all.
After some testing I discovered that the issue lies with using Qt classes within the signals. The following works fine:
//File.h
class MainGui : public QMainWindow
{
Q_OBJECT
public:
explicit MainGui(QWidget *parent = 0);
~MainGui();
signals:
void addItemSignal(void* it);
private slots:
void addItemImpl(void* it);
private:
Ui::MainGui *ui;
};
//File.cpp
void MainGui::addItemImpl(void*it)
{
//do anything
}
MainGui::MainGui(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainGui)
{
QObject::connect(this, &MainGui::addItemSignal,
this, &MainGui::addItemImpl);
}
MainGui::~MainGui()
{
delete ui;
}
This doesn't just affect custom signals but built-in ones too:
QObject::connect(models, &QStandardItemModel::dataChanged,[this](a b, x y){
//do something
});
This breaks the .dll as well.
I also noticed that I had to completely rebuild the .dll in Qt Creator to fix the problem. Removing any problematic signals and just building didn't fix the issue.
The error only happens when the Qt .dll is built in Debug configuration. Release config works well. Whether the MSVC program is Debug or Release seems to have no effect. I haven't changed any of the default settings for either of those configurations (other than a few things that definitely have nothing to do with it).
The only difference I found in Qt Creator between the two configurations is the call of qmake:
qmake.exe "D:\Dev\Qt Workspace\ArduGui\ArduGui.pro" -r -spec win32-msvc2013 "CONFIG+=debug" "CONFIG+=qml_debug"
This is the call for the Debug configuration. In Release the two debug config flags are missing. But when I messed around with the qmake arguments the result did not change. Debug config would always cause the entry point error, regardless of the presence of CONFIG+=debug or CONFIG+=qml_debug. Likewise, Release would always work even if the two flags are added.
So at this point I'm running against a wall. Does anyone have experience with this or can suggest options on how to debug the problem?
Some more info:
I'm using Windows 10, MSVC 2013 and Qt Creator 3.6 with Qt 5.5.1. Both the .exe and .dll are compiled with the MSVC++ 12.0 compiler through their respective IDEs.
If it works fine with void* but doesn't work with QT class pointer passed as argument, I guess you have not registered the class to be able to use it in signal/slot mechanism:
qRegisterMetaType<QGraphicsView *>("QGraphicsView*");
Be sure to call this function before your first use of this signal.
Though I'm not sure this is the cause of all your issues.

Qt creator cannot find, QTcpServer and QTcpSocket

Eventhough, I put 'network' in .pro file,
My Qt creator cannot find QTcpSocket and QTcpServer.
What should I do?
I remove the Qtcreator and redownloaded already but it also did not work.
My Linux version is Ubuntu 14.04 LTS
and I downloaded QT Creator by linux commands.
sudo apt-get install qtcreator
I even do the linus updates because I worried that I missed something.
sudo get-apt update
sudo get-apt upgrade
Why Qtcreator cannot perceive QTcpServer and QTcpSocket headers?
--------------*.pro -----------------------------------
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = server11
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
-------------------mainwindow.h--------------------------------------
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Did you install the complete framework? Or just the IDE?
Try downloading the Qt offline installer and downloading the framework through it. Download and install it from here.
Qt Open Source
Instructions for Ubuntu

Instantiating/Accessing COM API from Qt

I am trying to access a COM API of an application using Qt. However when I try to instantiate the COM API object I get:
D:\dev\git\com_example\Lights.h:441: error: undefined reference to `vtable for Lights::Application'
Now I know that this is normally associated with the fact that we have declared a method but not implemented it but I am using the Lights.tlb file provided by the SDK provider for the application and the Lights.h file referred to in the error message is auto-generated by Qt.
My .pro file is:
QT += core gui webkitwidgets network widgets sql axcontainer
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = com_example
TEMPLATE = app
TYPELIBS = $$system(dumpcpp Lights.tlb)
HEADERS += \
LightsInterface.h
SOURCES += main.cpp\
LightsInterface.cpp
The TYPELIBS bit is what converts the Lights.tlb file to Lights.h and Lights.cpp
This is all fine, the code builds but as soon as I try to create an instance of the COM API interface I get the error. The code that does this is:
#include <QWidget>
#include <QMainWindow>
#include "Lights.h"
class LightsInterface : public QMainWindow
{
Q_OBJECT
public:
explicit LightsInterface(QWidget *parent = 0);
signals:
public slots:
private:
Lights::Application app;
};
#endif // LIGHTSINTERFACE_H
Does anybody know what I am doing wrong? Are the Lights.h and Lights.cpp files not being generated correctly from the Lights.tlb file? Am I trying to instantiate the object incorrectly?
any help greatly appreciated.
thanks

Using Dlls in Qt C++

I'm trying to build a project with a library (dll) I made. I've never attempted to either load or make a library before and I'm getting the following error.
error: undefined reference to `imp__ZN6NeuronC1Ev'
In Qt, the error is shown in the following line.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) <--------------------------- Error indicated here.
{
ui->setupUi(this);
}
Project File
QT += core gui
TARGET = Jane
TEMPLATE = app
LIBS += -L quote(C:\Programming\Jane\Jane\Source\Neuron.dll)
SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.h
FORMS += MainWindow.ui
Here is one of the classes that I've exported
#ifndef NEURON_H
#define NEURON_H
#include <QList>
#include "Neuron_global.h"
#include <Sensor.h>
class NEURONSHARED_EXPORT Neuron
{
public:
explicit Neuron();
const double getOutput() const;
const double & getWeight() const;
void setWeight(const double& weight);
private:
double weight; // The weight of this neuron.
QList<Neuron*> neurons; // This Neuron's children.
QList<Sensor*> sensors; // This Neuron's Sensors.
};
#endif // NEURON_H
The NEURONSHARED_EXPORT Marco is defined in "Neuron_global.h"
#ifndef NEURON_GLOBAL_H
#define NEURON_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(NEURON_LIBRARY)
# define NEURONSHARED_EXPORT Q_DECL_EXPORT
#else
# define NEURONSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // NEURON_GLOBAL_H
If anyone has any advice on how to fix this, I would greatly appreciate it.
Edit:
I've added the libNeuron.a file to the LIBS argument in pro file. However, I'm now getting the following error.
LIBS += libNeuron.a
cannot find -lNeuron.a
any ideas?
What are you trying to do?
LIBS += -L quote(C:\Programming\Jane\Jane\Source\Neuron.dll)
It variable contains a lib-files, which project will be linked with, not a library itself!
You should find a lib for the dll or use WINAPI LoadLibrary/GetProcAddres functions to load dll dynamically.
This is only a quick guess of mine: your trouble is caused c++ name mangling. Google
"qt dll c++ name mangling"
and find some examples of working dll / client projects.
In this case everything looks right (assuming NEURON_LIBRARY is not defined since you're building under the app template, although Windows v. Linux act differently in this regard).
qmake is known not to pick up all the changes that it ought to so I'd recommend re-running qmake and then your make variant (e.g. make, gmake, nmake):
$ qmake
$ nmake
In some cases, you'll actually need to do a clean (or delete the relevant object files) before everything will be able to link correctly.