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

Movies - The Bubble (2022)

  Back to Evolution (2001) .

IT - Fixing Windows Error 1327: Account Restrictions Are Preventing This User from Signing In

Fixing Windows Error 1327: Account Restrictions Are Preventing This User from Signing In Introduction Error 1327, “Account restrictions are preventing this user from signing in,” is a perplexing and disruptive issue that occurs on some Windows 10 and Windows 11 machines. The message typically appears at login or while connecting to remote resources, like shared folders, network drives, or remote desktops. Table of Contents Symptoms of Error 1327 Common Causes Step-by-Step Troubleshooting Advanced Fixes Automation via PowerShell Prevention Tips Further Reading Symptoms of Error 1327 Users experiencing this error may encounter one or more of the following: Login screen fails after credentials are entered. Error message appears when accessing mapped drives or network resources. Remote Desktop Connection (RDP) is rejected with the 1327 message. Group Policy logon restrictions silently block access. Co...

IT - Troubleshooting Kodi DLNA Visibility Issues After Windows Updates: A Deep Dive Into Conflicts, Fixes, and Lessons Learned

Title: Troubleshooting Kodi DLNA Visibility Issues After Windows Updates: A Deep Dive Into Conflicts, Fixes, and Lessons Learned Subtitle: How I Diagnosed and Solved Intermittent Kodi Visibility Problems on a Samsung Smart TV After Windows OS Updates and Media Server Conflicts Introduction Home media streaming should be seamless, but anyone who has integrated Kodi into a smart home setup knows that stability isn't always guaranteed. Recently, I encountered a frustrating issue: Kodi, running perfectly on my Windows 10 Pro desktop, suddenly became invisible to my Samsung Smart TV via DLNA. The journey to resolve this seemingly simple visibility issue turned into a deep technical rabbit hole involving Windows Media Server, Universal Media Server, Jellyfin, NordVPN, and the very internals o... The System Setup Before diving into the problem, it's essential to understand my hardware and software setup: Operating System: Windows 10 Pro (build 2009) Media Server: Kodi (...