This post is a brief account of how to compile a QT GUI as part of a ROS catkin package.

I spent the past week migrating a ROS project to the latest release, ROS Groovy. A major change with this release is the deprecation of the build system rosbuild in favor of a new build system, catkin. Catkin is a light-weight wrapper for CMake. Overall, the migration went smoothly, but it took significantly longer than anticipated (which I probably should have anticipated). One sticking point was compiling our Operator Control Station (OCS) GUI, designed in QT4. The problems were related to the removal of QT-specific rosbuild macros for the CMakeLists.txt and the use of out of source builds by catkin.

The Setup

I used qt_ros to generate a QT form, an accompanying QMainWindow derived class, and a ROS interface class as the basis for the OCS. The original CMakeLists.txt was based on rosbuild and modifications for the transition to catkin. I relied on a variety of resources for the migration, since none of them seemed to have all the information I needed: catkin’s CMakeLists.txt overview, using CMake to build QT, rosbuild to catkin migration guide, and this post about using CMake with QT.

The Skinny

The OCS took significantly more work to catkinize than the rest of the nodes. The migration guide specifies how to transition many rosbuild macros to catkin, but the qt-specific ones are absent, specifically:

1
rosbuild_prepare_qt4(QtCore QtGui)

Using information from the first three of the above sources, I found a replacement to include the QT components I need:

1
2
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui)
include(${QT_USE_FILE})

The next problem involved catkin’s transition to out of source builds. A QT .ui file must be turned into an associated header file to be included in a project. All of the files built during a catkin build are placed in the build/ directory of the catkin workspace, not CMake’s current working directory. For someone trying to include a ui header file from an in source location, the standard include will fail because the ui’s header file ends up in buid/.

Once I figured this out, I found the last source, and the addition to the CMakeLists.txt was simple:

1
include_directories(${CMAKE_CURRENT_BINARY_DIR})

Now everything compiles and installs properly. The new CMakeLists are closer to pure CMake.

CMakeLists.txt

Below is the CMakeLists.txt I use to compile the OCS. Not included are some catkin and project dependencies passed in from parent directories. I want to offer this as a basic outline to compile and install a QT GUI using catkin and ROS Groovy because I was not able to find it anywhere else.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cmake_minimum_required(VERSION 2.8.3)
find_package(catkin REQUIRED COMPONENTS roscpp image_transport)
find_package(Qt4 REQUIRED COMPONENTS QtCore QtGui)

include(${QT_USE_FILE})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
file(GLOB QT_FORMS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.ui)
file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} resources/*.qrc)
file(GLOB_RECURSE QT_MOC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS *.hpp)

QT4_ADD_RESOURCES(QT_RESOURCES_CPP ${QT_RESOURCES})
QT4_WRAP_CPP(QT_MOC_HPP ${QT_MOC})
QT4_WRAP_UI(QT_FORMS_HPP ${QT_FORMS})

file(GLOB_RECURSE QT_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS *.cpp)

add_executable(ocs ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_FORMS_HPP} ${QT_MOC_HPP})
target_link_libraries(ocs ${QT_LIBRARIES} ${ROS_LIBRARIES} ${catkin_LIBRARIES})

install(TARGETS ocs
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

5 Comments

  • Billy

    Hi Brian. Many thanks for sharing this information. I’m having to go through a similar exercise, so this information is very helpful. Hopefully we won’t see further heavy-lifting of the ROS build infrastructure in the near future…
    Regards, Billy

  • Simon

    I was trying to build the talker-app from ROS’s beginner tutorials as Qt application just to check if it works. It actually worked with rosbuild, but now I’m trying to achieve this whole thing with catkin for the newer ROS versions.

    With your CMake I constantly get the following error:
    /home/simon/catkinws/src/beginner_qt/src/mainwindow.cpp:2:27: fatal error: ui_mainwindow.h: No such file or directory

    This file doesn’t exist in the src directory, but it is usually build from the .ui form file and can be included without further specification of the path in the .cpp file.

    Could you post a working example of a Qt project? I think that would help me a lot.

    • Is your ui_main_window.h created? It should be somewhere in your build/ directory with the output from the rest of the QT MOC process. Given your path, I’d guess it would be in /home/simon/catkinws/build/beginner_qt/src/

      Also, how are you including the .ui file? I use “ui_main_window.h” instead of <> since the .h file is generated inside the folder where the build takes place.

Leave a Reply