Skip to content

Commit

Permalink
Qt6 compatibility (#968)
Browse files Browse the repository at this point in the history
* Qt6 Compilation success

* Fixed qt5 backward compatibility

* Fixed build for qt<=5.9 (bionic)

* Added docker file for easy testing with latest Qt/VTK/PCL/OpenCV

* Fixed cmake for qt
  • Loading branch information
matlabbe authored Mar 6, 2023
1 parent 98635ae commit 8c5c4f6
Show file tree
Hide file tree
Showing 29 changed files with 255 additions and 77 deletions.
67 changes: 47 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ option(PCL_OMP "With PCL OMP implementations" ON)
ENDIF()

set(RTABMAP_QT_VERSION AUTO CACHE STRING "Force a specific Qt version.")
set_property(CACHE RTABMAP_QT_VERSION PROPERTY STRINGS AUTO 4 5)
set_property(CACHE RTABMAP_QT_VERSION PROPERTY STRINGS AUTO 4 5 6)

FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco xfeatures2d nonfree gpu cudafeatures2d)

Expand Down Expand Up @@ -297,28 +297,39 @@ IF(WITH_QT)
ENDIF(NOT VTK_FOUND)

# If Qt is here, the GUI will be built
# look for Qt5 (if vtk>5 is installed) before Qt4
IF("${VTK_MAJOR_VERSION}" GREATER 5)
if(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "5")
FIND_PACKAGE(Qt5 QUIET COMPONENTS Widgets Core Gui PrintSupport OpenGL OPTIONAL_COMPONENTS Svg)
ENDIF(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "5")
ENDIF("${VTK_MAJOR_VERSION}" GREATER 5)

IF(NOT Qt5_FOUND)
IF("${VTK_MAJOR_VERSION}" GREATER_EQUAL 9)
MESSAGE(STATUS "VTK>=9 detected, will use VTK_QT_VERSION=${VTK_QT_VERSION} for Qt version.")
IF(${VTK_QT_VERSION} EQUAL 6)
FIND_PACKAGE(Qt6 COMPONENTS Widgets Core Gui OpenGL PrintSupport QUIET OPTIONAL_COMPONENTS Svg)
ELSEIF(${VTK_QT_VERSION} EQUAL 5)
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui OpenGL PrintSupport QUIET OPTIONAL_COMPONENTS Svg)
ELSE()
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui OPTIONAL_COMPONENTS QtSvg)
ENDIF()
ELSE()
# look for Qt5 (if vtk>5 is installed) before Qt4
IF("${VTK_MAJOR_VERSION}" GREATER 5)
IF(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "5")
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui OpenGL PrintSupport QUIET OPTIONAL_COMPONENTS Svg)
ENDIF(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "5")
ENDIF("${VTK_MAJOR_VERSION}" GREATER 5)

IF(NOT Qt5_FOUND)
IF(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "4")
FIND_PACKAGE(Qt4 QUIET COMPONENTS QtCore QtGui OPTIONAL_COMPONENTS QtSvg)
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui OPTIONAL_COMPONENTS QtSvg)
ENDIF(RTABMAP_QT_VERSION STREQUAL "AUTO" OR RTABMAP_QT_VERSION STREQUAL "4")
ENDIF(NOT Qt5_FOUND)
ENDIF(NOT Qt5_FOUND)
ENDIF()

IF(QT4_FOUND OR Qt5_FOUND)
IF(QT4_FOUND OR Qt5_FOUND OR Qt6_FOUND)
IF("${VTK_MAJOR_VERSION}" EQUAL 5)
FIND_PACKAGE(QVTK REQUIRED) # only for VTK 5
ELSE()
list(FIND PCL_LIBRARIES VTK::GUISupportQt value)
IF(value EQUAL -1)
list(FIND PCL_LIBRARIES vtkGUISupportQt value)
IF(value EQUAL -1)
IF("${VTK_MAJOR_VERSION}" GREATER 8)
IF("${VTK_MAJOR_VERSION}" GREATER_EQUAL 9)
SET(PCL_LIBRARIES "${PCL_LIBRARIES};VTK::GUISupportQt")
ELSE()
SET(PCL_LIBRARIES "${PCL_LIBRARIES};vtkGUISupportQt")
Expand Down Expand Up @@ -354,7 +365,7 @@ IF(WITH_QT)

ENDIF()
ADD_DEFINITIONS(-DQT_NO_KEYWORDS) # To avoid conflicts with boost signals/foreach and Qt macros
ENDIF(QT4_FOUND OR Qt5_FOUND)
ENDIF(QT4_FOUND OR Qt5_FOUND OR Qt6_FOUND)
ENDIF(WITH_QT)

IF(NOT VTK_FOUND)
Expand Down Expand Up @@ -752,7 +763,18 @@ IF(WITH_ORB_SLAM AND NOT G2O_FOUND)
ENDIF(WITH_ORB_SLAM AND NOT G2O_FOUND)

IF(NOT MSVC)
IF((NOT WITH_MSCKF_VIO OR NOT msckf_vio_FOUND) AND (loam_velodyne_FOUND OR floam_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND OR Open3D_FOUND))
IF(Qt6_FOUND)
# Qt6 requires c++17
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
IF(COMPILER_SUPPORTS_CXX17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_CXX_STANDARD 17)
ELSE()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++17 support. Please use a different C++ compiler if you want to use Qt6.")
ENDIF()
ENDIF()
IF((NOT (${CMAKE_CXX_STANDARD} STREQUAL "17")) AND ((NOT WITH_MSCKF_VIO OR NOT msckf_vio_FOUND) AND (loam_velodyne_FOUND OR floam_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND OR Open3D_FOUND)))
#LOAM, PCL>=1.10, latest g2o and CCCoreLib require c++14, but MSCKF_VIO requires c++11
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
Expand All @@ -764,7 +786,7 @@ IF(NOT MSVC)
ENDIF()
ENDIF()

IF( (NOT (${CMAKE_CXX_STANDARD} STREQUAL "14")) AND (
IF( (NOT (${CMAKE_CXX_STANDARD} STREQUAL "17") AND NOT (${CMAKE_CXX_STANDARD} STREQUAL "14")) AND (
G2O_FOUND OR
GTSAM_FOUND OR
CERES_FOUND OR
Expand Down Expand Up @@ -796,7 +818,7 @@ ENDIF()

####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
IF(APPLE AND BUILD_AS_BUNDLE)
IF(Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))
IF(Qt6_FOUND OR Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))

# Required when packaging, and set CMAKE_INSTALL_PREFIX to "/".
SET(CMAKE_INSTALL_PREFIX "/")
Expand Down Expand Up @@ -1023,7 +1045,7 @@ IF(ANDROID)
IF(BUILD_APP)
ADD_SUBDIRECTORY( app )
ENDIF(BUILD_APP)
ELSEIF(Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))
ELSEIF(Qt6_FOUND OR Qt5_FOUND OR (QT4_FOUND AND QT_QTCORE_FOUND AND QT_QTGUI_FOUND))
ADD_SUBDIRECTORY( guilib )
IF(BUILD_APP)
ADD_SUBDIRECTORY( app )
Expand Down Expand Up @@ -1055,12 +1077,14 @@ ADD_CUSTOM_TARGET(uninstall
####
add_library(rtabmap INTERFACE)
add_library(rtabmap::rtabmap ALIAS rtabmap)
IF(QT4_FOUND OR Qt5_FOUND)
IF(QT4_FOUND OR Qt5_FOUND OR Qt6_FOUND)
set(CONF_WITH_GUI ON)
IF(QT4_FOUND)
set(CONF_QT_VERSION 4)
ELSE()
ELSEIF(Qt5_FOUND)
set(CONF_QT_VERSION 5)
ELSE()
set(CONF_QT_VERSION 6)
ENDIF()
target_link_libraries(rtabmap INTERFACE rtabmap_utilite rtabmap_core rtabmap_gui)
ELSE()
Expand Down Expand Up @@ -1271,6 +1295,9 @@ MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION}
ELSEIF(Qt5_FOUND)
MESSAGE(STATUS " With Qt ${Qt5_VERSION} = YES (License: Open Source or Commercial)")
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")
ELSEIF(Qt6_FOUND)
MESSAGE(STATUS " With Qt ${Qt6_VERSION} = YES (License: Open Source or Commercial)")
MESSAGE(STATUS " With VTK ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} = YES (License: BSD)")

ELSEIF(NOT WITH_QT)
MESSAGE(STATUS " With Qt = NO (WITH_QT=OFF)")
Expand Down
4 changes: 3 additions & 1 deletion RTABMapConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ find_dependency(OpenCV COMPONENTS core calib3d imgproc highgui stitching photo v
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_guiTargets.cmake")
find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization)

if(@CONF_QT_VERSION@ EQUAL 5)
if(@CONF_QT_VERSION@ EQUAL 6)
find_dependency(Qt6 COMPONENTS Widgets Core Gui OpenGL)
elseif(@CONF_QT_VERSION@ EQUAL 5)
find_dependency(Qt5 COMPONENTS Widgets Core Gui OpenGL)
else() # Qt4
find_dependency(Qt4 COMPONENTS QtCore QtGui)
Expand Down
2 changes: 1 addition & 1 deletion cmake_modules/FindZEDOC.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ENDIF (ZEDOC_INCLUDE_DIR AND ZEDOC_LIBRARY)

IF (ZEDOC_FOUND)
# show which ZEDOC was found only if not quiet
IF (NOT _FIND_QUIETLY)
IF (NOT ZEDOC_FIND_QUIETLY)
MESSAGE(STATUS "Found ZEDOC: ${ZEDOC_LIBRARIES}")
ENDIF (NOT ZEDOC_FIND_QUIETLY)
ELSE (ZEDOC_FOUND)
Expand Down
63 changes: 63 additions & 0 deletions docker/latest_deps/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

FROM osrf/ros:humble-desktop

# Install build dependencies
RUN apt-get update && \
apt-get install -y git software-properties-common ros-humble-rtabmap-ros libqt6* qt6* && \
apt-get remove -y ros-humble-rtabmap libpcl* libqt5* qt5* libvtk* libopencv* && \
apt-get clean && rm -rf /var/lib/apt/lists/

WORKDIR /root/

RUN rm /bin/sh && ln -s /bin/bash /bin/sh

# ros2 seems not sourcing by default its multi-arch folders
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ros/humble/lib/x86_64-linux-gnu

# Build latest VTK with Qt6
RUN git clone https://github.com/Kitware/VTK.git && \
cd VTK && \
mkdir build && \
cd build && \
cmake -DVTK_GROUP_ENABLE_Qt=YES .. && \
make -j$(nproc) && \
make install && \
cd ../.. && \
rm -rf VTK

# Build latest PCL with latest VTK
RUN git clone https://github.com/PointCloudLibrary/pcl.git && \
cd pcl && \
mkdir build && \
cd build && \
cmake -DBUILD_tools=OFF .. && \
make -j$(nproc) && \
make install && \
cd ../.. && \
rm -rf pcl

# Build latest OpenCV
RUN git clone https://github.com/opencv/opencv.git && \
git clone https://github.com/opencv/opencv_contrib.git && \
cd opencv && \
mkdir build && \
cd build && \
cmake -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \
make -j$(nproc) && \
make install && \
cd ../.. && \
rm -rf opencv

# Copy current source code
COPY . /root/rtabmap

# Build RTAB-Map project
RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \
cmake .. && \
make -j$(nproc) && \
make install && \
cd ../.. && \
rm -rf rtabmap && \
ldconfig

4 changes: 3 additions & 1 deletion examples/NoEventsExample/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ endif()

IF(QT4_FOUND)
QT4_WRAP_CPP(moc_srcs MapBuilder.h)
ELSE()
ELSEIF(Qt5_FOUND)
QT5_WRAP_CPP(moc_srcs MapBuilder.h)
ELSE()
QT6_WRAP_CPP(moc_srcs MapBuilder.h)
ENDIF()

ADD_EXECUTABLE(noEventsExample main.cpp ${moc_srcs})
Expand Down
4 changes: 3 additions & 1 deletion examples/RGBDMapping/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ endif()

IF(QT4_FOUND)
QT4_WRAP_CPP(moc_srcs MapBuilder.h)
ELSE()
ELSEIF(Qt5_FOUND)
QT5_WRAP_CPP(moc_srcs MapBuilder.h)
ELSE()
QT6_WRAP_CPP(moc_srcs MapBuilder.h)
ENDIF()

ADD_EXECUTABLE(rgbd_mapping main.cpp ${moc_srcs})
Expand Down
4 changes: 3 additions & 1 deletion examples/WifiMapping/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ endif()

IF(QT4_FOUND)
QT4_WRAP_CPP(moc_srcs MapBuilder.h MapBuilderWifi.h)
ELSE()
ELSEIF(Qt5_FOUND)
QT5_WRAP_CPP(moc_srcs MapBuilder.h MapBuilderWifi.h)
ELSE()
QT6_WRAP_CPP(moc_srcs MapBuilder.h MapBuilderWifi.h)
ENDIF()

SET(srcs
Expand Down
3 changes: 2 additions & 1 deletion guilib/include/rtabmap/gui/ConsoleWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtCore/QMutex>
#include <QtCore/QTimer>
#include <QtCore/QTime>
#include <QtCore/QElapsedTimer>

class Ui_consoleWidget;
class QMessageBox;
Expand Down Expand Up @@ -69,7 +70,7 @@ private Q_SLOTS:
QMutex _errorMessageMutex;
QMutex _msgListMutex;
QTimer _timer;
QTime _time;
QElapsedTimer _time;
QTextCursor * _textCursor;
QList<QPair<QString, int> > _msgList;
};
Expand Down
5 changes: 3 additions & 2 deletions guilib/include/rtabmap/gui/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/utilite/UEventsHandler.h"
#include <QMainWindow>
#include <QtCore/QSet>
#include <QElapsedTimer>
#include "rtabmap/core/RtabmapEvent.h"
#include "rtabmap/core/SensorData.h"
#include "rtabmap/core/OdometryEvent.h"
Expand Down Expand Up @@ -400,8 +401,8 @@ protected Q_SLOTS:
bool _processingOdometry;

QTimer * _oneSecondTimer;
QTime * _elapsedTime;
QTime * _logEventTime;
QElapsedTimer * _elapsedTime;
QElapsedTimer * _logEventTime;

PdfPlotCurve * _posteriorCurve;
PdfPlotCurve * _likelihoodCurve;
Expand Down
2 changes: 1 addition & 1 deletion guilib/include/rtabmap/gui/ProgressDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class RTABMAP_GUI_EXPORT ProgressDialog : public QDialog
Q_OBJECT

public:
ProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
ProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = Qt::WindowFlags());
virtual ~ProgressDialog();

void setEndMessage(const QString & message) {_endMessage = message;} // Message shown when the progress is finished
Expand Down
5 changes: 3 additions & 2 deletions guilib/include/rtabmap/utilite/UPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <QLabel>
#include <QPushButton>
#include <QtCore/QTime>
#include <QtCore/QElapsedTimer>

class QGraphicsView;
class QGraphicsScene;
Expand Down Expand Up @@ -602,9 +603,9 @@ private Q_SLOTS:
UOrientableLabel * _yLabel;
QLabel * _refreshRate;
QString _workingDirectory;
QTime _refreshIntervalTime;
QElapsedTimer _refreshIntervalTime;
int _lowestRefreshRate;
QTime _refreshStartTime;
QElapsedTimer _refreshStartTime;
QString _autoScreenCaptureFormat;
QPoint _mousePressedPos;
QPoint _mouseCurrentPos;
Expand Down
9 changes: 7 additions & 2 deletions guilib/src/3rdParty/QMultiComboBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#include "QMultiComboBox.h"
#include <QApplication>
#include <QCoreApplication>
#include <QDesktopWidget>
#include <QWindow>
#include <QScreen>

#include "rtabmap/utilite/ULogger.h"

Expand Down Expand Up @@ -46,7 +47,11 @@ QMultiComboBox::~QMultiComboBox()
void QMultiComboBox::SetDisplayText(QString text)
{
m_DisplayText_ = text;
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
const int textWidth = fontMetrics().horizontalAdvance(text);
#else
const int textWidth = fontMetrics().width(text);
#endif
setMinimumWidth(textWidth + 30);
updateGeometry();
repaint();
Expand Down Expand Up @@ -88,7 +93,7 @@ void QMultiComboBox::showPopup()
//QRect rec2(p , p + QPoint(rec.width(), rec.height()));

// get the two possible list points and height
QRect screen = QApplication::desktop()->screenGeometry(this);
QRect screen = this->window()->windowHandle()->screen()->availableGeometry();
QPoint above = this->mapToGlobal(QPoint(0,0));
int aboveHeight = above.y() - screen.y();
QPoint below = this->mapToGlobal(QPoint(0,rec.height()));
Expand Down
16 changes: 13 additions & 3 deletions guilib/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,14 @@ IF(QT4_FOUND)
#This will generate moc_* for Qt
QT4_WRAP_CPP(moc_srcs ${headers_ui})
### Qt Gui stuff end###
ELSE()
ELSEIF(Qt5_FOUND)
QT5_ADD_RESOURCES(srcs_qrc ${qrc})
QT5_WRAP_UI(moc_uis ${uis})
QT5_WRAP_CPP(moc_srcs ${headers_ui})
ELSE()
QT6_ADD_RESOURCES(srcs_qrc ${qrc})
QT6_WRAP_UI(moc_uis ${uis})
QT6_WRAP_CPP(moc_srcs ${headers_ui})
ENDIF()


Expand Down Expand Up @@ -140,8 +144,14 @@ ENDIF(QT4_FOUND)
SET(LIBRARIES "")
SET(PUBLIC_LIBRARIES "")

IF(Qt5_FOUND)
SET(PUBLIC_LIBRARIES ${PUBLIC_LIBRARIES} Qt5::Widgets Qt5::Core Qt5::Gui)
IF(Qt6_FOUND)
SET(PUBLIC_LIBRARIES ${PUBLIC_LIBRARIES} Qt6::Widgets Qt6::Core Qt6::Gui Qt6::OpenGL)
SET(LIBRARIES ${LIBRARIES} Qt6::PrintSupport)
IF(Qt6Svg_FOUND)
SET(LIBRARIES ${LIBRARIES} Qt6::Svg)
ENDIF()
ELSEIF(Qt5_FOUND)
SET(PUBLIC_LIBRARIES ${PUBLIC_LIBRARIES} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::OpenGL)
SET(LIBRARIES ${LIBRARIES} Qt5::PrintSupport)
IF(Qt5Svg_FOUND)
SET(LIBRARIES ${LIBRARIES} Qt5::Svg)
Expand Down
Loading

0 comments on commit 8c5c4f6

Please sign in to comment.