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
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:- Adding widgets to Qt Designer
- how do i create a custom (widget) plugin for qt designer with cmake ( and visual studio )
- how to create plugins (Qt 5.2.0)
- QT Docs: QDesignerCustomWidgetInterface
- QT Docs: Creating Custom Widgets for Qt Designer
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