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

Movie - The Wizard of Oz (1939)

  My views Plot In rural  Kansas ,  Dorothy Gale  lives on a farm owned by her Uncle Henry and Aunt Em, and wishes she could be somewhere else. Dorothy's neighbor, Almira Gulch, who had been bitten by Dorothy's dog, Toto, obtains a sheriff's order authorizing her to seize Toto. Toto escapes and returns to Dorothy, who runs away to protect him. Professor Marvel, a charlatan fortune-teller, convinces Dorothy that Em is heartbroken, which prompts Dorothy to return home. She returns just as a  tornado  approaches the farm. Unable to get into the locked storm cellar, Dorothy takes cover in the farmhouse and is knocked unconscious. She seemingly awakens to find the house moving through the air, with her and Toto still inside it. The house comes down in an unknown land, and Dorothy is greeted by a good witch named  Glinda , who floats down in a bubble and explains that Dorothy has landed in Munchkinland in the  Land of Oz , and that the Munchkins are cel...

Movie - Se7en (1995)

  My views Plot In an unnamed city overcome with violent crime and corruption, disillusioned police Detective Lieutenant William Somerset is one week from retirement. He is partnered with David Mills, a young, short-tempered, idealistic detective who recently relocated to the city with his wife, Tracy. On Monday, Somerset and Mills investigate an obese man who was forced to eat until his stomach burst, killing him. The detectives find the word " gluttony " written on a wall. Somerset, considering the case too extreme for his last investigation, asks to be reassigned, but his request is denied. The following day, another victim, who had been forced to cut one pound (0.45 kg) of flesh from his body, is found; the crime scene is marked " greed ." Clues at the scene lead Somerset and Mills to the  sloth  victim, a drug-dealing  pederast  whom they find emaciated and restrained to a bed. Photographs reveal the victim was restrained for precisely one year. Somers...

IT - Which Is Faster: find | cpio -pdvm OR rsync?

To determine which is faster between find | cpio -pdvm and rsync for copying a large directory tree locally, we need to consider several factors: the nature of the operation, the tools' design, the system environment, and the specific use case. Let’s break this down based on the information provided in the web results and general knowledge about these tools. Overview of the Tools find | cpio -pdvm : find : Recursively lists all files and directories in a given path. cpio : A tool for copying files into or out of a cpio or tar archive. In this case, with the -pdvm options: -p : Pass-through mode (copy files from one directory tree to another). -d : Create directories as needed. -v : Verbose mod...