En esta página

Plugin de widget personalizado

Creación de un plugin de widget personalizado para Qt Widgets Designer.

Captura de pantalla de un widget de reloj analógico en Qt Widgets Designer

En este ejemplo, el widget personalizado utilizado se basa en el ejemplo Reloj analógico y no proporciona ninguna señal o ranura personalizada.

Preparación

Para proporcionar un widget personalizado que se pueda utilizar con Qt Widgets Designer, necesitamos proporcionar una implementación autónoma y proporcionar una interfaz de plugin. En este ejemplo, reutilizamos el ejemplo del reloj analógico por comodidad.

Archivos del proyecto

CMake

Los archivos del proyecto necesitan indicar que un plugin enlazado a las librerías de Qt Widgets Designer debe ser construido:

find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets)

qt_add_plugin(customwidgetplugin)

target_link_libraries(customwidgetplugin PUBLIC
    Qt::Core
    Qt::Gui
    Qt::UiPlugin
    Qt::Widgets
)

La lista de bibliotecas de enlace especifica Qt::UiPlugin. Esto indica que el plugin sólo utiliza las interfaces abstractas QDesignerCustomWidgetInterface y QDesignerCustomWidgetCollectionInterface y no tiene enlace con las bibliotecas Qt Widgets Designer. Cuando se accede a otras interfaces de Qt Widgets Designer que tienen vinculación, se debe utilizar Designer en su lugar; esto asegura que el plugin se vincula dinámicamente a las bibliotecas Qt Widgets Designer y tiene una dependencia en tiempo de ejecución de las mismas.

El siguiente ejemplo muestra cómo añadir los archivos de cabecera y fuente del widget:

target_sources(customwidgetplugin PRIVATE
    analogclock.cpp analogclock.h
    customwidgetplugin.cpp customwidgetplugin.h
)

Proporcionamos una implementación de la interfaz del plugin para que Qt Widgets Designer pueda utilizar el widget personalizado.

También es importante asegurarse de que el plugin se instala en una ubicación que sea buscada por Qt Widgets Designer. Hacemos esto especificando una ruta de destino para el proyecto y añadiéndolo a la lista de elementos a instalar:

   set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer")
install(TARGETS customwidgetplugin
    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

El widget personalizado se crea como una biblioteca. Se instalará junto con los demás plugins de Qt Widgets Designer cuando se instale el proyecto (utilizando ninja install o un procedimiento de instalación equivalente).

Para más información sobre plugins, consulte la documentación Cómo crear plugins de Qt.

qmake

El siguiente ejemplo muestra cómo vincular un plugin a las bibliotecas Qt Widgets Designer:

CONFIG      += plugin
TEMPLATE    = lib

QT          += widgets uiplugin

La variable QT contiene la palabra clave uiplugin, que equivale a la biblioteca Qt::UiPlugin.

El siguiente ejemplo muestra cómo añadir los archivos de cabecera y fuente del widget:

HEADERS     = analogclock.h \
              customwidgetplugin.h
SOURCES     = analogclock.cpp \
              customwidgetplugin.cpp
OTHER_FILES += analogclock.json

El siguiente ejemplo muestra cómo instalar un plugin en la ruta de plugins de Qt Widgets Designer:

TARGET = $$qtLibraryTarget($$TARGET)

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

Definición e implementación de la clase AnalogClock

La clase AnalogClock se define e implementa exactamente del mismo modo que se describe en el ejemplo del Reloj analógico. Dado que la clase es autónoma y no requiere ninguna configuración externa, puede utilizarse sin modificaciones como widget personalizado en Qt Widgets Designer.

Definición de la clase AnalogClockPlugin

La clase AnalogClock está expuesta a Qt Widgets Designer a través de la clase AnalogClockPlugin. Esta clase hereda tanto de QObject como de la clase QDesignerCustomWidgetInterface, e implementa una interfaz definida por QDesignerCustomWidgetInterface.

Para asegurar que Qt reconoce el widget como un plugin, exporta la información relevante sobre el widget añadiendo la macro Q_PLUGIN_METADATA():

class AnalogClockPlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
    Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
    explicit AnalogClockPlugin(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;
};

Las funciones proporcionan información sobre el widget que Qt Widgets Designer puede utilizar en la caja del widget. La variable miembro privada initialized se utiliza para registrar si el plugin ha sido inicializado por Qt Widgets Designer.

Tenga en cuenta que la única parte de la definición de la clase que es específica para este widget personalizado en particular es el nombre de la clase.

Implementación de AnalogClockPlugin

El constructor de la clase simplemente llama al constructor de la clase base QObject y establece la variable initialized a false.

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

Qt Widgets El diseñador inicializará el plugin cuando sea necesario llamando a la función initialize():

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

    initialized = true;
}

En este ejemplo, la variable privada initialized se comprueba, y sólo se establece en true si el plugin no está ya inicializado. Aunque este complemento no requiere que se ejecute ningún código especial cuando se inicializa, podríamos incluir dicho código después de la prueba de inicialización.

La función isInitialized() permite a Qt Widgets Designer saber si el plugin está listo para su uso:

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

Las instancias del widget personalizado son suministradas por la función createWidget(). La implementación del reloj analógico es sencilla:

QWidget *AnalogClockPlugin::createWidget(QWidget *parent)
{
    return new AnalogClock(parent);
}

En este caso, el widget personalizado sólo requiere que se especifique parent. Si es necesario proporcionar otros argumentos al widget, pueden introducirse aquí.

Las siguientes funciones proporcionan información para que Qt Widgets Designer la utilice para representar el widget en la caja de widgets. La función name() devuelve el nombre de la clase que proporciona el widget personalizado:

QString AnalogClockPlugin::name() const
{
    return u"AnalogClock"_s;
}

La función group() se utiliza para describir el tipo de widget al que pertenece el widget personalizado:

QString AnalogClockPlugin::group() const
{
    return u"Display Widgets [Examples]"_s;
}

El widget plugin se colocará en una sección identificada por su nombre de grupo en la caja de widgets de Qt Widgets Designer. El icono utilizado para representar el widget en la caja de widgets es devuelto por la función icon():

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

En este caso, devolvemos un icono nulo para indicar que no tenemos ningún icono que pueda utilizarse para representar el widget.

Para la entrada del widget personalizado en la caja de widgets se puede proporcionar una sugerencia y la ayuda "¿Qué es esto? La función toolTip() debe devolver un mensaje corto que describa el widget:

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

La función whatsThis() puede devolver una descripción más larga:

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

La función isContainer() indica a Qt Widgets Designer si el widget debe utilizarse como contenedor de otros widgets. Si no es así, Qt Widgets Designer no permitirá al usuario colocar widgets en su interior.

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

La mayoría de los widgets en Qt pueden contener widgets hijos, pero sólo tiene sentido usar widgets contenedores dedicados para este propósito en Qt Widgets Designer. Devolviendo false, indicamos que el widget personalizado no puede contener otros widgets; si devolviéramos true, Qt Widgets Designer permitiría colocar otros widgets dentro del reloj analógico y definir un diseño.

La función domXml() proporciona una forma de incluir ajustes por defecto para el widget en el formato XML estándar utilizado por Qt Widgets Designer. En este caso, sólo especificamos la geometría del widget:

QString AnalogClockPlugin::domXml() const
{
    return uR"(
<ui language="c++">
  <widget class="AnalogClock" name="analogClock">
)"
R"(
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>100</width>
        <height>100</height>
      </rect>
    </property>
")
R"(
    <property name="toolTip">
      <string>The current time</string>
    </property>
    <property name="whatsThis">
      <string>The analog clock widget displays the current time.</string>
    </property>
  </widget>
</ui>
)"_s;
}

Si el widget proporciona una sugerencia de tamaño razonable, no es necesario definirla aquí. Además, devolver una cadena vacía en lugar de un elemento <widget> indicará a Qt Widgets Designer que no instale el widget en la caja de widgets.

Para que las aplicaciones puedan utilizar el widget del reloj analógico, implementamos la función includeFile() para devolver el nombre del archivo de cabecera que contiene la definición de la clase del widget personalizado:

QString AnalogClockPlugin::includeFile() const
{
    return u"analogclock.h"_s;
}

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.