En esta página

Creación de widgets personalizados para Qt Widgets Designer

Qt Widgets La arquitectura basada en plugins de Designer permite que los widgets personalizados definidos por el usuario y por terceros se editen igual que se hace con los widgets Qt estándar. Todas las características del widget personalizado están disponibles en Qt Widgets Designer, incluyendo las propiedades, señales y ranuras del widget. Dado que Qt Widgets Designer utiliza widgets reales durante el proceso de diseño del formulario, los widgets personalizados aparecerán igual que cuando se previsualizan.

El módulo QtDesigner permite crear widgets personalizados en Qt Widgets Designer.

Primeros pasos

Para integrar un widget personalizado en Qt Widgets Designer, necesita una descripción adecuada para el widget y un archivo de proyecto apropiado.

Descripción de la interfaz

Para informar a Qt Widgets Designer sobre el tipo de widget que desea proporcionar, cree una subclase de QDesignerCustomWidgetInterface que describa las distintas propiedades que expone su widget. La mayoría de ellas son proporcionadas por funciones que son puramente virtuales en la clase base, ya que sólo el autor del plugin puede proporcionar esta información.

FunciónDescripción del valor de retorno
name()El nombre de la clase que proporciona el widget.
group()El grupo de la caja de widgets de Qt Widgets Designer al que pertenece el widget.
toolTip()Una breve descripción para ayudar a los usuarios a identificar el widget en Qt Widgets Designer.
whatsThis()Una descripción más larga del widget para los usuarios de Qt Widgets Designer.
includeFile()El archivo de cabecera que debe incluirse en las aplicaciones que utilicen este widget. Esta información se almacena en archivos UI y será utilizada por uic para crear una declaración #includes adecuada en el código que genera para el formulario que contiene el widget personalizado.
icon()Un icono que puede ser utilizado para representar el widget en la caja de widgets de Qt Widgets Designer.
isContainer()True si el widget se utilizará para contener widgets hijos; false en caso contrario.
createWidget()Un puntero QWidget a una instancia del widget personalizado, construido con el padre suministrado.

Nota: createWidget() es una función de fábrica responsable únicamente de la creación del widget. Las propiedades del widget personalizado no estarán disponibles hasta que vuelva load().

domXml()Una descripción de las propiedades del widget, como su nombre de objeto, sugerencia de tamaño y otras propiedades estándar de QWidget.
codeTemplate()Esta función está reservada para un uso futuro en Qt Widgets Designer.

También se pueden reimplementar otras dos funciones virtuales:

initialize()Establece extensiones y otras características para widgets personalizados. Las extensiones de contenedor personalizadas (véase QDesignerContainerExtension) y las extensiones de menú de tareas (véase QDesignerTaskMenuExtension) deben configurarse en esta función.
isInitialized()Devuelve true si el widget ha sido inicializado; devuelve false en caso contrario. Las reimplementaciones suelen comprobar si se ha llamado a la función initialize() y devuelven el resultado de esta comprobación.

Notas sobre la función domXml()

La función domXml() devuelve un fragmento de archivo de interfaz de usuario que es utilizado por la fábrica de widgets de Qt Widgets Designer para crear un widget personalizado y sus propiedades aplicables.

Desde Qt 4.4, la caja de widgets de Qt Widgets Designer permite que un archivo UI completo describa un widget personalizado. El archivo UI puede ser cargado usando la etiqueta <ui>. Especificar la etiqueta <ui> permite añadir el elemento <customwidget> que contiene información adicional para los widgets personalizados. La etiqueta <widget> es suficiente si no se necesita información adicional.

Si el widget personalizado no proporciona una sugerencia de tamaño razonable, es necesario especificar una geometría por defecto en la cadena devuelta por la función domXml() en su subclase. Por ejemplo, el AnalogClockPlugin proporcionado por el ejemplo Custom Widget Plugin, define una widgetgeometry por defecto de la siguiente manera:

    ...
R"(
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>100</width>
        <height>100</height>
      </rect>
    </property>
")
    ...

Una característica adicional de la función domXml() es que, si devuelve una cadena vacía, el widget no se instalará en la caja de widgets de Qt Widgets Designer. Sin embargo, todavía puede ser utilizado por otros widgets en el formulario. Esta característica se utiliza para ocultar widgets que no deben ser creados explícitamente por el usuario, pero que son requeridos por otros widgets.

Una especificación completa de un widget personalizado tiene el siguiente aspecto:

<ui language="c++"> displayname="MyWidget">
    <widget class="widgets::MyWidget" name="mywidget"/>
    <customwidgets>
        <customwidget>
            <class>widgets::MyWidget</class>
            <addpagemethod>addPage</addpagemethod>
            <propertyspecifications>
                <stringpropertyspecification name="fileName" notr="true" type="singleline"/>
                <stringpropertyspecification name="text" type="richtext"/>
                <tooltip name="text">Explanatory text to be shown in Property Editor</tooltip>
            </propertyspecifications>
        </customwidget>
    </customwidgets>
</ui>

Atributos de la etiqueta <ui>:

AtributoPresenciaValoresComentario
languageopcional"c++", "jambi"Este atributo especifica el lenguaje al que está destinado el widget personalizado. Sirve principalmente para evitar que aparezcan plugins C++ en Qt Jambi.
displaynameopcionalNombre de la claseEl valor del atributo aparece en la caja Widget y puede usarse para eliminar espacios de nombres.

La etiqueta <addpagemethod> indica a Qt Widgets Designer y uic qué método debe usarse para añadir páginas a un widget contenedor. Esto se aplica a los widgets contenedores que requieren llamar a un método concreto para añadir un hijo en lugar de añadir el hijo pasando el padre. En particular, esto es relevante para los contenedores que no son una subclase de los contenedores proporcionados en Qt Widgets Designer, sino que se basan en la noción de Página actual. Además, es necesario proporcionar una extensión de contenedor para ellos.

El elemento <propertyspecifications> puede contener una lista de metainformación de propiedades.

La etiqueta <tooltip> puede utilizarse para especificar un tool tip que se mostrará en el Editor de Propiedades al pasar el ratón por encima de la propiedad. El nombre de la propiedad se indica en el atributo name y el texto del elemento es el tooltip. Esta funcionalidad se añadió en Qt 5.6.

Para las propiedades de tipo cadena, se puede utilizar la etiqueta <stringpropertyspecification>. Esta etiqueta tiene los siguientes atributos:

AtributoPresenciaValoresComentario
nameobligatorioNombre de la propiedad
typeobligatorioVer tabla inferiorEl valor del atributo determina cómo los manejará el editor de propiedades.
notropcional"true", "false"Si el atributo es "true", el valor no debe traducirse.

Valores del atributo type de la propiedad string:

ValorTipo
"richtext"Texto enriquecido.
"multiline"Texto plano de varias líneas.
"singleline"Texto sin formato de una línea.
"stylesheet"Una hoja de estilo CSS.
"objectname"Un nombre de objeto (conjunto restringido de caracteres válidos).
"url"URL, nombre de archivo.

Requisitos del plugin

Para que los plugins funcionen correctamente en todas las plataformas, debe asegurarse de que exportan los símbolos que necesita Qt Widgets Designer.

En primer lugar, la clase del plugin debe ser exportada para que el plugin sea cargado por Qt Widgets Designer. Para ello, utilice la macro Q_PLUGIN_METADATA(). También, la macro QDESIGNER_WIDGET_EXPORT debe ser usada para definir cada clase de widget personalizado dentro de un plugin, que Qt Widgets Designer instanciará.

Creando Widgets de Buen Comportamiento

Algunos widgets personalizados tienen características especiales de interfaz de usuario que pueden hacer que se comporten de manera diferente a muchos de los widgets estándar que se encuentran en Qt Widgets Designer. Específicamente, si un widget personalizado toma el teclado como resultado de una llamada a QWidget::grabKeyboard(), la operación de Qt Widgets Designer se verá afectada.

Para dar a los widgets personalizados un comportamiento especial en Qt Widgets Designer, proporcione una implementación de la función initialize() para configurar el proceso de construcción del widget para un comportamiento específico de Qt Widgets Designer. Esta función será llamada por primera vez antes de cualquier llamada a createWidget() y podría quizás establecer una bandera interna que pueda ser comprobada más tarde cuando Qt Widgets Designer llame a la función createWidget() del plugin.

Construyendo e Instalando el Plugin

Un plugin simple

El Custom Widget Plugin muestra un sencillo plugin Qt Widgets Designer.

El archivo de proyecto para un plugin debe especificar las cabeceras y fuentes tanto para el widget personalizado como para la interfaz del plugin. Normalmente, este archivo sólo tiene que especificar que el proyecto del plugin se construirá como una biblioteca, pero con soporte específico de plugin para Qt Widgets Designer. Para CMake, esto se hace con las siguientes declaraciones:

find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets)

qt_add_plugin(customwidgetplugin)
target_sources(customwidgetplugin PRIVATE
    analogclock.cpp analogclock.h
    customwidgetplugin.cpp customwidgetplugin.h
)
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 ningún 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.

También es necesario asegurarse de que el plugin se instala junto con otros plugins de widgets de Qt Widgets Designer:

   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}"
)

Para qmake:

CONFIG      += plugin
TEMPLATE    = lib
HEADERS     = analogclock.h \
              customwidgetplugin.h
SOURCES     = analogclock.cpp \
              customwidgetplugin.cpp
OTHER_FILES += analogclock.json

La variable QT contiene la palabra clave uiplugin, que es el equivalente de la biblioteca Qt::UiPlugin.

También es necesario asegurarse de que el plugin se instala junto con otros plugins de widgets de Qt Widgets Designer:

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

La variable $[QT_INSTALL_PLUGINS] es un marcador de posición de la ubicación de los plugins Qt instalados. Puedes configurar Qt Widgets Designer para que busque plugins en otras ubicaciones configurando la variable de entorno QT_PLUGIN_PATH antes de ejecutar la aplicación.

Nota: Qt Widgets Designer buscará un subdirectorio designer en cada ruta suministrada.

Consulte QCoreApplication::libraryPaths() para obtener más información sobre la personalización de rutas para bibliotecas y plugins con aplicaciones Qt.

Si los plugins están construidos en un modo incompatible con Qt Widgets Designer, no serán cargados ni instalados. Para más información sobre plugins, vea el documento Plugins HOWTO.

Dividiendo el Plugin

El enfoque simple explicado anteriormente introduce un problema particularmente cuando se utilizan las otras interfaces de Qt Widgets Designer que tienen vinculación: La aplicación que utilice el widget personalizado dependerá entonces de las cabeceras y librerías de Qt Widgets Designer. En un escenario del mundo real, esto no es lo deseado.

Las siguientes secciones describen cómo resolverlo.

Vinculación del widget a la aplicación

Cuando se utiliza qmake, el archivo fuente y de cabecera del widget personalizado puede compartirse entre la aplicación y Qt Widgets Designer creando un archivo .pri para su inclusión:

INCLUDEPATH += $$PWD
HEADERS += $$PWD/analogclock.h
SOURCES += $$PWD/analogclock.cpp

Este archivo sería entonces incluido por el archivo .pro del plugin y la aplicación:

include(customwidget.pri)

Cuando se utiliza CMake, los archivos fuente del widget pueden añadirse de forma similar al proyecto de la aplicación.

Compartir el widget mediante una biblioteca

Otro método consiste en colocar el widget en una biblioteca vinculada al plugin Qt Widgets Designer y a la aplicación. Se recomienda utilizar bibliotecas estáticas para evitar problemas de localización de la biblioteca en tiempo de ejecución.

Para bibliotecas compartidas, vea Crear bibliotecas compartidas.

Uso del plugin con QUiLoader

La forma preferida de añadir widgets personalizados a QUiLoader es subclasificarla reimplementando QUiLoader::createWidget().

Sin embargo, también es posible utilizar plugins de widgets personalizados de Qt Widgets Designer (ver QUiLoader::pluginPaths() y funciones relacionadas). Para evitar tener que desplegar las librerías Qt Widgets Designer en el dispositivo de destino, esos plugins no deberían tener ningún enlace con las librerías Qt Widgets Designer (QT = uiplugin, ver Creating Custom Widgets for Qt Widgets Designer#BuildingandInstallingthePlugin).

Para más información sobre el uso de widgets personalizados en Qt Widgets Designer, consulte los ejemplos Custom Widget Plugin y Task Menu Extension para más información sobre el uso de widgets personalizados en Qt Widgets Designer. Además, puede utilizar la clase QDesignerCustomWidgetCollectionInterface para combinar varios widgets personalizados en una única biblioteca.

© 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.