Skip to main content

How to Create Qt Designer Plug-ins

 Source links:

  • https://doc.qt.io/qt-6/plugins-howto.html
  • https://doc.qt.io/qt-6/designer-creating-custom-widgets.html
  • https://www.typeerror.org/docs/qt~6.1/designer-creating-custom-widgets

Notes:

  • plug-in should be compiled by a compiler that produces an ABI as QT Designer (Help > About Qt Creator). On my case, MSVC 2019, 64-bits. Since there is an ABI compatibility, I am using MSVC 2017, 64-bits.
  • plug-ins should be stored in C:\Qt\Qt5.12.12\Tools\QtCreator\bin\plugins\designer, or similar folder, depending on which version of Qt you are using.
  • plug-ins can be activated while Qt Creator is in use. Just copy the new DLL into the folder above and refresh the plug-ins.
    • Edit a form, any form. Even an empty form.
    • Go to Tools > Form editor > About Qt Designer Plug-ins
    • Click refresh
  • plug-ins cannot be updated while QT Designer is open. You need to close it and then copy the updated version of the DLL into the folder above.
  • Unless specified in the plug-in, Qt Designer always converts to lowercase the name of the .h files. It is very important to pay attention to it when writing the plug-in.
  • If the class in the <customwidgets> does not exist as promoted or QT Designer object, the <header> entry, if there any upper-case letters, will be striped the .h extension.  I guess this is to be aligned with the Qt standard of #include <QString>  becoming #include "../qstring./h"
  • At the bottom of any .ui file which uses this new widget, you should find something like this:
    .
    .
    .
     <customwidgets>
      <customwidget>
       <class>ToolButton</class>
       <extends>QToolButton</extends>
       <header>ToolButton.h</header>
      </customwidget>
     </customwidgets>

Step 1: Create your own new class

  1. Create your class .h
    ToolButton.h

    #ifndef TOOLBUTTON_H
    #define TOOLBUTTON_H

    #include <QToolButton>
    #include <QtUiPlugin/QDesignerExportWidget>

    class QDESIGNER_WIDGET_EXPORT ToolButton 
      : public QToolButton
    {
      Q_OBJECT
    private:
    protected:
    public:
      explicit ToolButton(QWidget*a_pParent = nullptr);
    };
    #endif
  2. Create your class .cpp
    ToolButton.cpp

    #include "ToolButton.h"

    ToolButton::ToolButton(QWidget * a_pParent) 
      : QToolButton(a_pParent) 
    {
      this->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
      this->setIconSize(QSize(24,24));
      this->setMinimumSize(48, 44);
    }

Step 2: Create the plug-in, which will interface between your new class and QT Designer

  • The return string from domXml() defines the initial values for the widget in QT Designer. You can return whatever you want on it. There are some tags defined here that you can also use. Personally I always include <author>, <comment>, and <locale>. You can add any property from any sub-class. You can add even other objects. This is very much an entire .ui file if you want.
  • It is important to pay attention on the return object from includeFile(). You can use upper/lower case combination but there is always the risk of QT Designer converting all to lower-case. Very annoying.
  • Pay a good attention to the use of R"( and )".

  1. Create your plug-in .h
    ToolButton_PlugIn.h

    #ifndef TOOLBUTTONPLUGIN_H
    #define TOOLBUTTONPLUGIN_H

    #include <QtUiPlugin/QDesignerCustomWidgetInterface>

    class ToolButton_PlugIn
      : public QObject,
        public QDesignerCustomWidgetInterface
    {
        Q_OBJECT
        Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
        Q_INTERFACES(QDesignerCustomWidgetInterface)

    public:
        explicit ToolButton_PlugIn(QObject *parent = nullptr);

        bool isContainer() const override;
        bool isInitialized() const override;
        QIcon icon() const override;
        QString domXml() const override;
        QString group() const override;
        QString includeFile() const override;
        QString name() const override;
        QString toolTip() const override;
        QString whatsThis() const override;
        QWidget *createWidget(QWidget *parent) override;
        void initialize(QDesignerFormEditorInterface *core) override;

    private:
        bool initialized = false;
    };

    #endif
  2. Create your plug-in .cpp
    ToolButton_PlugIn.cpp

    #include "ToolButton.h"
    #include "ToolButton_PlugIn.h"

    #include <QtPlugin>

    ToolButton_PlugIn::ToolButton_PlugIn(QObject *parent)
        : QObject(parent)
    {
    }

    void ToolButton_PlugIn::initialize(QDesignerFormEditorInterface * /* core */)
    {
        if (initialized)
            return;

        initialized = true;
    }

    bool ToolButton_PlugIn::isInitialized() const
    {
        return initialized;
    }

    QWidget *ToolButton_PlugIn::createWidget(QWidget *parent)
    {
        return new ToolButton(parent);
    }

    QString ToolButton_PlugIn::name() const
    {
        return QStringLiteral("ToolButton");
    }

    QString ToolButton_PlugIn::group() const
    {
        return QStringLiteral("My Personal Widgets");
    }

    QIcon ToolButton_PlugIn::icon() const
    {
        return QIcon();
    }

    QString ToolButton_PlugIn::toolTip() const
    {
        return QString();
    }

    QString ToolButton_PlugIn::whatsThis() const
    {
        return QString();
    }

    bool ToolButton_PlugIn::isContainer() const
    {
        return false;
    }

    QString ToolButton_PlugIn::domXml() const
    {
        return R"(
    <ui language="c++">
     <author>Andreas Friedrich Berendsen</author>
     <comment>Copyright (c) 2014-2022 by Andreas Friedrich Berendsen</comment>
     <widget class="ToolButton" name="m_ToolButton">
      <property name="locale"><locale language="English" country="UnitedKingdom"/></property>
      <property name="geometry">"
       <rect>"
        <x>0</x>"
        <y>0</y>
        <width>48</width>
        <height>44</height>
       </rect>
      </property>
     </widget>
    </ui>)";
    }

    QString ToolButton_PlugIn::includeFile() const
    {
        return QStringLiteral("ToolButton.h");
    }
  3. Create your plug-in .pro
    ToolButton_PlugIn.pro

    QT          += widgets uiplugin

    QTDIR_build {
      # This is only for the Qt build. Do not use externally. We mean it.
      PLUGIN_TYPE = designer
      PLUGIN_CLASS_NAME = ToolButton_PlugIn
      load(qt_plugin)
      CONFIG += install_ok
    } else {
      # Public example:
      CONFIG      += plugin
      TEMPLATE    = lib
      TARGET = $$qtLibraryTarget($$TARGET)

      target.path = $$[QT_INSTALL_PLUGINS]/designer
      INSTALLS += target

    }

    HEADERS     = ToolButton.h \
                  ToolButton_PlugIn.h
    SOURCES     = ToolButton.cpp \
                  ToolButton_PlugIn.cpp
    OTHER_FILES += ToolButton.json

Comments

Popular posts from this blog

TV Series - The Brokenwood Mysteries [NZ] (2014) - Season 10

 

Movie - Sin City: A Dame to Kill For (2014)

 

Movies - Deadpool & Wolverine (2024)