Adding some qt tools in choreonoid

Hello everyone,
I’ve imported Choreonoid into QTcreator for developing my plugin. I would like to add a Qcustomplot tool to my custom Choreonoid plugin, and my cmakelist.txt for the plugin is as follows:

if(NOT ENABLE_GUI)
  return()
endif()

set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set(CMAKE_AUTOMOC ON)

# Find the QtWidgets library
find_package(Qt5Widgets)
find_package(Qt5PrintSupport)
find_package(Qt5OpenGL)
find_package(Qt5Gui)

option(BUILD_SURENA "Building a sample plugin \"SURENA\"" OFF)
configure_file(surena4offline.cnoid ${CNOID_SOURCE_SHARE_DIR}/project COPYONLY)

set(sources
  Sources/Robot.cpp
  Sources/LinkM.cpp
  Sources/TaskSpace.cpp
  Sources/MinimumJerkInterpolation.cpp
  Sources/taskspaceoffline.cpp
)


set(headers
  Headers/Robot.h
  Headers/LinkM.h
  Headers/TaskSpace.h
  Headers/MinimumJerkInterpolation.h
  Headers/taskspaceoffline.h
  Headers/qcustomplot.h
)

if(BUILD_SURENA)
  add_cnoid_simple_controller(SURENAOffline SURENA4Offline.cpp ${sources}  ${headers})

add_cnoid_simple_controller(SURENA4Online SURENA4Online.cpp ${sources} ${headers})
configure_file(surena4online.cnoid ${CNOID_SOURCE_SHARE_DIR}/project COPYONLY)


add_cnoid_simple_controller(SURENA4PDTest SURENA4PDTest.cpp ${sources} ${headers})
configure_file(surena4PDtest.cnoid ${CNOID_SOURCE_SHARE_DIR}/project COPYONLY)

include_directories (${PROJECT_SOURCE_DIR}/Headers)
  ADD_LIBRARY(qcustomplot
   SHARED
   ${headers}
   ${sources}
   Sources/qcustomplot.cpp)


  if(QT5)
    qt5_use_modules(SURENAOffline Core Widgets  PrintSupport )
  endif()

if(QT5)
    qt5_use_modules(SURENA4Online Core  Widgets  PrintSupport )
  endif()

if(QT5)
    qt5_use_modules(SURENA4PDTest Core  Widgets  PrintSupport )
  endif()

endif()


qt5_wrap_cpp(plot_moc Headers/qcustomplot.h)

target_link_libraries(qcustomplot
     Qt5::Core
    ${Qt5Widgets_LIBRARIES}
    Qt5::PrintSupport
    ${QT_LIBRARIES}
    CnoidBodyPlugin)

install_sample_source(sources)

I have tested similiar cmakelist in a seperate project and I have worked with qcustom plot in cmake and it works, however during building this cmakelist within choreonoid I have reicived the following error:

In file included from /home/milad/software/choreonoid/choreonoid-1.6.0/sample/SURENA/Sources/qcustomplot.cpp:26:0:

/home/milad/software/choreonoid/choreonoid-1.6.0/sample/SURENA/Headers/qcustomplot.h:725:1: error: 'signals' does not name a type

signals:

Thanks in advance for your help.

I guess Choreonoid structure have a problem with “signals:” in Qcustomplot and does not recognize the signals keyword.

Hi,

Choreonoid not only use Qt, but also boost.
In such case, we have to face with “signal” keyword collision problem.
http://blog.qt.io/blog/2007/06/15/boost-signals-slots-with-qt/

As written in the link above, most standard way to avoid this problem is to disable the Qt “signal” keyword by adding “no_keyword” option to the compiler. Choreonoid CMakeList.txt is already configured to add this option (that is why you face with the compile error).

You will have to use “Q_SLOTS” macro instead of “signal” under this configuration as shown in the example below.

Best,

Thank you very much. I’ve changed emit to Q_EMITS, forearch to Q_FOREACH and signals to Q_SIGNALS and the problem solved.
I need a Qwidget to correspond the Qcustomplot to this. By this mean at a first step, I’ve tried to make a simple plugin that by clicking a button it opens new empty window however after running Choreonoid when I click on the button, the Choreonoid window will close and will exit and give the following error.

symbol lookup error: /home/milad/software/choreonoid/choreonoid-1.6.0/lib/choreonoid-1.6/libCnoidHelloWorldPlugin.so: undefined symbol: _ZN11MainWindow1C1EP7QWidget

( It just a simple code that opens the empty form by clicking a button in Choreonoid) my codes are as following:
cmakelists.txt:

    if(NOT ENABLE_GUI)
      return()
    endif()
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    set(CMAKE_AUTOMOC ON)

    find_package(Qt5Widgets)
    find_package(Qt5PrintSupport)
    find_package(Qt5OpenGL)
    find_package(Qt5Gui)
    find_package(Qt5Core)

    option(BUILD_HELLO_WORLD_SAMPLE "Building a Hello World sample plugin" OFF)

    set (My_ui  mainwindow1.ui
          )

    #set (MyProjectBin_src ${PROJECT_SOURCE_DIR}/main.cpp)

    qt5_wrap_ui (My_ui_moc  ${My_ui})
    include_directories (${PROJECT_SOURCE_DIR})

    if(BUILD_HELLO_WORLD_SAMPLE)
      set(target CnoidHelloWorldPlugin)

    ADD_LIBRARY(choreonoidsurena2
     SHARED
     mainwindow1.h
     mainwindow1.cpp
     ${My_ui_moc}
    )
      add_cnoid_plugin(${target} SHARED HelloWorldPlugin.cpp)
      target_link_libraries(choreonoidsurena2
        ${target}
        CnoidBase
         Qt5::Core
        ${Qt5Widgets_LIBRARIES}
        Qt5::PrintSupport
        ${QT_LIBRARIES}
                 )
      apply_common_setting_for_plugin(${target})

      if(QT5)
        qt5_use_modules(${target}  Core Widgets  PrintSupport)
      endif()
    endif()

    install_sample_source(HelloWorldPlugin.cpp)

helloWorldplugin .cpp:

#include <cnoid/Plugin>
#include <cnoid/MenuManager>
#include <cnoid/MessageView>
#include <mainwindow1.h>
#include <QApplication>
#include <QWidget>
#include <QMainWindow>
using namespace std;
using namespace cnoid;

class HelloWorldPlugin : public Plugin
{
public:
    
    HelloWorldPlugin() : Plugin("HelloWorld")
    {

    }
    
    virtual bool initialize()
    {
        Action* menuItem = menuManager().setPath("/View").addItem("Hello World");
        menuItem->sigTriggered().connect(bind(&HelloWorldPlugin::onHelloWorldTriggered, this));
        return true;
    }

private:
    
    void onHelloWorldTriggered()
    {
        MessageView::instance()->putln("Hello World !");
    MainWindow1 mainwindow1;
   mainwindow1.show();
    }
};

CNOID_IMPLEMENT_PLUGIN_ENTRY(HelloWorldPlugin)

mainwindow1.h:

#ifndef MAINWINDOW1_H
#define MAINWINDOW1_H

#include <QMainWindow>

namespace Ui {
class MainWindow1;
}

class MainWindow1 : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow1(QWidget *parent = 0);
    ~MainWindow1();

private:
    Ui::MainWindow1 *ui;
};

#endif // MAINWINDOW1_H

mainwindow1.cpp:

#include "mainwindow1.h"
#include "ui_mainwindow1.h"
#include <QWidget>
#include <QMainWindow>
MainWindow1::MainWindow1(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow1)
{
    ui->setupUi(this);
}

MainWindow1::~MainWindow1()
{
    delete ui;
}

There is also a mainwindow1.ui file. Would you please guide me how can I solve this problem?

Thanks in advance for your time.

Best regards,
Milad

Hi,

In your CMakeLists.txt file, I see you are trying to create two shared libraries (“CnoidHelloWorldPlugin” and “choreonoidsurena2”).
I think the reason of the error is the function MainWindow1::MainWindow1(QWidget*) only exist in “choreonoidsurena2” library and is not installed in the place where Choreonoid can find.

Suggestion: Why not compile the plugin into a single library?

1 Like