Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt5 - CMake - Add custom widget to Designer



  • I'm new to Qt and I found my self stuck by trying to add a custom widget to the Qt Designer. I would like to receive some help if any of you knows how to do that.


    What I'm using:

    OS: Windows

    IDE: Clion/Qt Creator

    CMake: 3.5

    Qt: 5


    What I'm trying to do:

    I've created a button called PolygonButtonWidget(cpp/h) which contains the implementation of that button. Also, I've created a PolygonWidgetPlugin(cpp/h) which consists of the necessary interfaces to add my custom widget to the Designer.

    In short terms, I'm trying to make my button to be displayed here
    enter image description here
    I tried to follow those references but I get stuck because there are either use Qt4 instead of Qt5 or they are using .pro file instead of CMake like me.
    Links:


    What I did so far:

    My CMake:

    So... So far as I understood I need to have 2 cakes, one it's for the actual project and the other one it's for my library (for my custom widget).

    Project CMake:

    cmake_minimum_required(VERSION 3.5)
    
    project(Qt-MainWindow LANGUAGES CXX)
    
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})
    include(windeployqt)
    
    find_package(Qt5 COMPONENTS Widgets Core Gui REQUIRED)
    
    get_target_property(QtCore_location Qt5::Core LOCATION)
    set(QT_MINGW ${QtCore_location}/../..)
    message(${QT_MINGW})
    
    add_executable(Vlad-Qt-MainWindow
            main.cpp
            mainwindow.cpp
            mainwindow.h
            mainwindow.ui
            )
    
    add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy ${QT_MINGW}/bin/libgcc_s_seh-1.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>
            COMMAND ${CMAKE_COMMAND} -E copy ${QT_MINGW}/bin/libstdc++-6.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>
            COMMAND ${CMAKE_COMMAND} -E copy ${QT_MINGW}/bin/libwinpthread-1.dll $<TARGET_FILE_DIR:${PROJECT_NAME}>
    
            COMMENT "Deploy mingw runtime libraries from ${QT_MINGW}/bin"
            )
    
    target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets Qt5::Core Qt5::Gui)
    
    windeployqt(${PROJECT_NAME})
    

    Custom Widget CMake:

    cmake_minimum_required(VERSION 3.5)
    set(PLUGIN PluginPrj)
    project(${PLUGIN})
    
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    
    set(SOURCES
            PolygonWidgetPlugin.cpp
            PolygonButtonWidget.cpp
            )
    
    set(HEADERS
            PolygonWidgetPlugin.h
            PolygonButtonWidget.h
            )
    
    find_package(Qt5 REQUIRED Core Gui Designer)
    include_directories(${CMAKE_CURRENT_BINARY_DIR})
    add_definitions(-DQT_PLUGIN)
    add_definitions(-DQT_NO_DEBUG)
    add_definitions(-DQT_SHARED)
    add_definitions(-DQDESIGNER_EXPORT_WIDGETS)
    
    add_library(${PLUGIN} SHARED
            ${SOURCES}
            ${HEADERS}
            )
    target_link_libraries(${PLUGIN} ${QT_LIBRARIES})
    
    install(TARGETS ${PLUGIN}
            DESTINATION ${QT_PLUGINS_DIR}/designer
            )
    

    PolygonButtonWidget.h

    class PolygonButtonWidget : public QWidget{
    Q_OBJECT
    
    public:
        explicit PolygonButtonWidget(QWidget *parent = nullptr);
    
        ~PolygonButtonWidget() override;
    
    protected:
        void paintEvent(QPaintEvent *event) override;
    
        void mousePressEvent(QMouseEvent *event) override;
    private:
        std::vector<QPoint> m_polygon;
        bool inside(QPoint point, std::vector<QPoint> polygon);
    };
    

    PolygonWidgetPlugin.cpp

    #include <QtCore/qplugin.h>
    #include <QtUiPlugin/QDesignerCustomWidgetInterface>
    
    class PolygonWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface{
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
        Q_INTERFACES(QDesignerCustomWidgetInterface)
    public:
        explicit PolygonWidgetPlugin(QObject *parent = nullptr);
    
        QString name() const override;
    
        QString includeFile() const override;
    
        QString group() const override;
    
        QIcon icon() const override;
    
        QString toolTip() const override;
    
        QString whatsThis() const override;
    
        bool isContainer() const override;
    
        QWidget *createWidget(QWidget *parent) override;
    
        bool isInitialized() const override;
    
        void initialize(QDesignerFormEditorInterface *core) override;
    
    private:
        bool initialized = false;
    };
    

    I'm not going to post the .cpp file because there is no point, but all of those functions are implemented based on the links from the references that I post above.


    So based on what I wrote about could any of you explain to me what I'm doing wrong? And why my custom widget is not displayed in that list? Or any other list? In PolygonWidgetPlugin::group()
    I'm returing return tr("New Group");, so I was expecting to see another group named "New Group".



  • Do you actually want it displayed in the menu or you just want to be able to use it in your designer?
    If it's the second it's super easy, just promote a widget



  • @VRonin I would prefer to display on the menu, not just to use it.


Log in to reply