Adding some qt tools in choreonoid


#1

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.


#2

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


#3

Hi,

Choreonoid not only use Qt, but also boost.
In such case, we have to face with “signal” keyword collision problem.

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,


#4

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


#5

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?