How to subclass QGLWidget to use glew? - qt

I'm struggling to get a subclass of QGLWidget compiled that uses glew. I'm running Qt 5.0.1 + MinGW 4.7 on Windows 7. Glew 1.7.0 has been compiled with said MinGW.
I have subclassed QGLWidget with UGGLWidget and included "GL/glew.h" before the QGLWidget includes. When compiling I get 200 Errors about:
'function' redeclared as different kind of symbol
conflicting declaration 'typedef'
So my Question:
How do I get a subclass of QGLWidget that uses glew compiled under Qt5?
Edit: I tried the same approach with another setup (Qt4.7 + MinGW4.4). It compiles and runs just fine. I have also tried using a more recent version of glew (Qt5.0.1 + MinGW4.7 + glew1.9.0) this doesn't compile either and gives the same compilation errors.
Here's a messy snippet of the compiler output:
> In file included from
> ..\..\..\..\..\..\Qt\Qt5.0.1\5.0.1\mingw47_32\include/QtGui/qopengl.h:55:0,
> from ..\..\..\..\..\..\Qt\Qt5.0.1\5.0.1\mingw47_32\include\QtOpenGL/qgl.h:47,
> from ..\..\..\..\..\..\Qt\Qt5.0.1\5.0.1\mingw47_32\include\QtOpenGL/QGLWidget:1,
> from src\UGGLWidget.h:4,
> from src\UGGLWidget.cpp:2: ..\..\..\..\..\..\Qt\Qt5.0.1\5.0.1\mingw47_32\include/GLES2/gl2.h:614:153:
> error: 'void __glewVertexAttribPointer(GLuint, GLint, GLenum,
> GLboolean, GLsizei, const GLvoid*)' redeclared as different kind of
> symbol In file included from src\UGGLWidget.cpp:1:0:
> ..\3rdPartyLibs\glew\include/GL/glew.h:13609:46: error: previous
> declaration of 'void (__attribute__((__stdcall__)) *
> __glewVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*)'
Last but not least the header and source file of the subclass. It's really just empty for now.
Source:
//UGGLWidget.cpp
#include "GL/glew.h"
#include "UGGLWidget.h"
UGGLWidget::UGGLWidget(QWidget *parent) : QGLWidget(parent) { ... }
Header:
//UGGLWidget.h
#ifndef UGGLWIDGET_H
#define UGGLWIDGET_H
#include <QGLWidget>
class UGGLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit UGGLWidget(QWidget *parent = 0);
};
#endif // UGGLWIDGET_H
Oh, and maybe relevant parts from the .pro file
QT += core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
LIBS += -L$$quote(../3rdPartyLibs/glew/lib/) -lglew32
LIBS += -lopengl32 -lglu32
INCLUDEPATH += $$quote(../3rdPartyLibs/glew/include)

The following fixed my problem, this goes everywhere, where I include glew:
#include "GL/glew.h"
#define QT_NO_OPENGL_ES_2
Another option: building Qt5.0.1 from source with -opengl desktop during the configure step.
For some reason QT_OPENGL_ES_2 is defined in my Qt5.0.1 installation. Looking through the inlcudes from QGLWidget.h I found the following in QtCore/qconfig.h
#if defined(QT_OPENGL_ES_2) && defined(QT_NO_OPENGL_ES_2)
# undef QT_OPENGL_ES_2
#elif !defined(QT_OPENGL_ES_2)
# define QT_OPENGL_ES_2
#endif
This leads to inclusion of GLES2/gl2.h which doesn't get along with glew. Knowing that the issue was related to GLES2 I came across a bug report and a QtProject post.
If I understand correctly, then the provided QtSDK installer for Qt5.0.1 has been built such that GLES is enabled.
Have a good day,
~Moritz

Note that QT 4.8RC release notes say:
Including QtOpenGL will not work in combination with GLEW, as QGLFunctions will undefine GLEW's defines.

Related

How to add defines to moc via cmake

I have a header like this:
#ifdef WITH_QT
#include <QObject>
#endif
namespace foo {
#ifdef WITH_QT
Q_NAMESPACE
#endif
enum class Letters {A, B, C };
#ifdef WITH_QT
Q_ENUM_NS(Letters)
#endif
}
And a cmake file:
cmake_minimum_required(VERSION 3.13)
find_package(Qt5 COMPONENTS Core)
qt5_wrap_cpp(moc_source foo.h)
add_library(foo STATIC ${moc_source})
target_compile_definitions(foo PUBLIC WITH_QT)
make VERBOSE=1 shows (abbreviated):
/usr/bin/moc foo.h
foo.h:0: Note: No relevant classes found. No output generated.
moc needs to be run with
/usr/bin/moc -DWITH_QT foo.h
CMake isn't forwarding your compile definitions to moc. That prevents those macros from existing, and inhibits moc from finding anything useful to generate.
A few solutions:
This will add WITH_QT globally:
add_definitions(-DWITH_QT)
This more refined method will tell qt5_wrap_cpp to import the compile definitions of a specific target. This is better as it avoids contaminating the compile definitions of the rest of your project.
qt5_wrap_cpp(moc_source foo.h TARGET foo)
See https://doc.qt.io/qt-5/qtcore-cmake-qt5-wrap-cpp.html for qt5_wrap_cpp() usage.
Use AUTOMOC by changing your CMakeLists to:
cmake_minimum_required(VERSION 3.13)
find_package(Qt5 COMPONENTS Core)
set(CMAKE_AUTOMOC ON)
add_library(foo STATIC foo.h)
target_compile_definitions(foo PUBLIC WITH_QT)
All three solutions will give you an archive with the missing symbol:
$ nm -gC libfoo.a
moc_foo.cpp.o:
U _GLOBAL_OFFSET_TABLE_
U qt_version_tag
0000000000000000 D foo::staticMetaObject

Including Eigen with QtCreator - Red errors showing in source file even though the code works?

I have just started using QtCreator (and C++ after 15 years away from it). I want to do some linear algebra stuff so I have included the library Eigen in my project file as follows (I have placed the Eigen library directly in my project for the moment):
INCLUDEPATH = "/home/Software/QtProjects/MyProject/eigen/"
My source file is:
#include <QCoreApplication>
#include <iostream>
#include <Eigen/Dense> % 'Eigen/Dense' file not found
using Eigen::MatrixXd; % use of undeclared identifier 'Eigen'
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MatrixXd m(2,2); % unknown type name 'MatrixXd'
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = 8;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;
return a.exec();
}
This code works and outputs the values of the matrix m in the console. However, in the QtCreator IDE, I have several error messages which I have included above as comments on the lines at which they appear.
So is there some way to fix this and make QtCreator stop showing these lines as errors when the code is actually working fine?
Try without quotation marks; and with += instead of =; INCLUDEPATH += /home/Software/QtProjects/MyProject/eigen/.
Go to Build > Run qmake to validate changes in the pro file.
INCLUDEPATH in qmake project file doesn't work
Qt creator Adding external library
How to add include path in Qt Creator?
On Linux, run
sudo apt-get install libeigen3-dev
Then add this to your .pro file
INCLUDEPATH += /usr/include/eigen3
And then run qmake

Crash on QwtPlotZoomer in QT5

I am trying to use a QwtPlotZoomer in QT5, but I get a seg fault when its constructor runs.
class Qwt_widget : public QwtPlot
{
Q_OBJECT
public:
Qwt_widget(QWidget* parent = 0) :
QwtPlot(parent),
m_canvas()
{
QwtPlotZoomer zoomer(&m_canvas); // Crashes here
}
private:
QwtPlotCanvas m_canvas;
};
The above widget is added to a simple main window so that it will be created (full code at https://github.com/chrisburnham/Qwt_qt5_crash). Also here are the QWT lines that I have added to the QT creators default pro file:
INCLUDEPATH += /usr/include/qwt
LIBS += -lqwt-qt5
I am running on Ubuntu 18.04 and installed Qt5 with libqt5-default (5.9.5) and QWT with libqwt-qt5-dev (6.1.3). I have checked all my libraries with LDD and looked at the headers I am using and they are all coming from the packages that were installed with libqwt-qt5-dev. I have previously used QwtPlotZoomers in this way in Qt4 (with the Qt4 version of QWT) and as far as I can tell from the documentation it should still work here.
You need to assign the QwtPlotCanvas to the QwtPlot before you ask QwtPlotZoomer to work on it. Note that QwtPlot::setCanvas() takes ownership, so do not use a member variable for the canvas.
But since you are using a default QwtPlotCanvas and not some derived class you could probably just use the canvas QwtPlot comes with:
QwtPlotZoomer zoomer(this->canvas()); // Should not crash here

CLion Arduino undefined reference

I have tried most of the suggestion regarding this issue to no avail.
I have created an Arduino project in CLion(version 2017.3.2) with Arduino plugin (version 1.2.3). I kept getting "undefined reference" during build.
My main Sample.ino file is:
#include <Arduino.h>
#include "Hello.h"
void setup() {
}
void loop() {
Hello::world();
}
and the Hello.h is simply:
#ifndef SAMPLE_HELLO_H
#define SAMPLE_HELLO_H
struct Hello {
static void world();
};
#endif //SAMPLE_HELLO_H
the Hello.cpp is
#include "Hello.h"
void Hello::world() {
}
and the CMakeLists.txt is:
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(PROJECT_NAME Sample)
project(${PROJECT_NAME})
set(${CMAKE_PROJECT_NAME}_SKETCH src/Sample.ino)
#include_directories(include)
include_directories(src)
#### Uncomment below additional settings as needed.
set(${CMAKE_PROJECT_NAME}_BOARD mega)
set(${CMAKE_PROJECT_NAME}_PORT /dev/ttyACM0)
set(mega.build.mcu atmega2560)
# set(mega.upload.protocol wiring)
set(mega.upload.speed 115200)
generate_arduino_firmware(${CMAKE_PROJECT_NAME})
All source files are under the folder src/,
Any suggestion to what have I missed?
I had the same problem and spent several hours to find a solution.
Arduino plugin uses arduino-cmake to build project. According to its documentation, to use generate_arduino_firmware command you should specify SKETCH or SRCS option.
If I define SKETCH option , I has no success to link additional files (hello.cpp).
So I try to use SRCS. Seems that if I define SKETCH and SRCS simultaneously, SRCS is be ignored. Another problem is when I specify src/sample.ino in SRCS option I have the same error.
So I do the following to compile the project successfully:
Renamed src/sample.ino into src/sample.cpp.
Commented out SKETCH and add SRCS option to list all source files:
set(${PROJECT_NAME}_SRCS src/sample.cpp src/hello.cpp)
Full CMakeList.txt is
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(CMAKE_CXX_STANDARD 14)
set(PROJECT_NAME Sample)
project(${PROJECT_NAME})
set(${PROJECT_NAME}_BOARD uno)
set(${PROJECT_NAME}_SRCS src/sample.cpp src/hello.cpp)
set(${PROJECT_NAME}_PROGRAMMER arduinoasisp)
set(${PROJECT_NAME}_PORT COM17)
set(${PROJECT_NAME}_AFLAGS -v)
generate_arduino_firmware(${PROJECT_NAME})
The Arduino support plugin uses arduino-cmake which has a bug causing your SRCS and HDRS to be erased when compiling a sketch.
You can read my bug report and proposed fix here. Basically you want to modify cmake/Platform/Arduino.cmake
Change line 1808 to avoid overwriting your sources
set(ALL_SRCS ${SKETCH_SOURCES})
set(ALL_SRCS ${ALL_SRCS} ${SKETCH_SOURCES})
Change line 1821 to recompile when a source changes
DEPENDS ${MAIN_SKETCH} ${SKETCH_SOURCES}
DEPENDS ${MAIN_SKETCH} ${ALL_SRCS}
I had that problem too.
Adding this to the CMakeLists made it work:
include_directories(${PROJECT_SOURCE_DIR})
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)
file(GLOB HDR_FILES ${PROJECT_SOURCE_DIR}/*.h)
set(PROJ_SRC ${SRC_FILES})
set(PROJ_HDR ${HDR_FILES})
generate_arduino_firmware(${CMAKE_PROJECT_NAME}
SRCS ${PROJ_SRC}
HDRS ${PROJ_HDR}
)
I'm not sure if that's the best solution but it worked in my case.

Getting values from pro files in Qt

I am using Qt 4.5 in Windows XP. My pro file has the variable VERSION = 1.0. Now i need to read this variable and get its value (1.0) from the source code. So that I don't have to maintain another variable for version inside my source code. I just read from the pro file and update it. So that the value remains consistent all over my project. Is it possible? Any pointers regarding this are welcome..
Use somethings like this:
DEFINES += VERSION=\\\"$$VERSION\\\"
This will define a macro that you can use in C source code. Get rid of the backslashes and quotes if you want a number, not a string.
I'll elaborate on this a bit.
In the YourApp.pro:
VERSION = 0.0.0.1
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
In the main.cpp:
#include <QApplication>
QCoreApplication::setApplicationVersion(QString(APP_VERSION));
Wherever else in your sources, e.g. in the imaginary controller.cpp:
#include <QApplication>
QString yourAppVersion = QCoreApplication::applicationVersion();
somehow, when I tried qDebug() << QString(APP_VERSION); in a class.cpp not in main.cpp. has an error "C2065" APP_VERSION: undeclared identifier". but when I tried in main.cpp that worked.

Resources