En esta página

ShaderEffect QML Type

Aplica shaders personalizados a un rectángulo. Más...

Import Statement: import QtQuick
Inherits:

Item

Propiedades

Descripción detallada

El tipo ShaderEffect aplica un shader personalizado vertex y fragment (pixel) a un rectángulo. Permite añadir efectos como sombra, desenfoque, color y page curl a la escena QML.

Nota: En función del backend de scenegraph Qt Quick que se utilice, es posible que el tipo ShaderEffect no sea compatible. Por ejemplo, con el backend software los efectos no se renderizarán en absoluto.

Sombreadores

En Qt 5, los efectos se proporcionaban en forma de código fuente GLSL (OpenGL Shading Language), a menudo incrustados como cadenas en QML. A partir de Qt 5.8, también es posible hacer referencia a archivos, ya sean locales o del sistema de recursos de Qt.

En Qt 6, Qt Quick tiene soporte para APIs gráficas, como Vulkan, Metal y Direct3D 11 también. Por lo tanto, trabajar con cadenas fuente GLSL ya no es factible. En su lugar, la nueva canalización de sombreado se basa en la compilación de código GLSL compatible con Vulkan en SPIR-V, seguido de la recopilación de información de reflexión y la traducción a otros lenguajes de sombreado, como HLSL, el Metal Shading Language y varias versiones de GLSL. Los recursos resultantes se empaquetan en un único paquete, normalmente almacenado en archivos con la extensión .qsb. Este proceso se realiza sin conexión o, como muy tarde, en el momento de compilación de la aplicación. En tiempo de ejecución, el gráfico de la escena y la abstracción gráfica subyacente consumen estos archivos .qsb. Por lo tanto, ShaderEffect espera referencias a archivos (locales o qrc) en Qt 6 en lugar de código shader en línea.

Las propiedades vertexShader y fragmentShader son URLs en Qt 6, y funcionan de forma muy similar a Image.source, por ejemplo. Sin embargo, sólo los esquemas file y qrc son compatibles con ShaderEffect. También es posible omitir el esquema file, permitiendo especificar una ruta relativa de forma conveniente. Dicha ruta se resuelve de forma relativa a la ubicación del componente (el archivo .qml ).

Entradas y recursos del sombreador

Hay dos tipos de entradas para el vertexShader: uniformes y entradas de vértices.

Las siguientes entradas están predefinidas:

  • vec4 qt_Vertex con ubicación 0 - posición del vértice, el vértice superior izquierdo tiene posición (0, 0), el inferior derecho (width, height).
  • vec2 qt_MultiTexCoord0 con ubicación 1 - coordenada de textura, la coordenada superior izquierda es (0, 0), la inferior derecha (1, 1). Si supportsAtlasTextures es true, las coordenadas se basarán en la posición en el atlas.

Nota: En la práctica, sólo importa la posición de entrada de los vértices. Los nombres son libremente cambiables, mientras que la localización debe ser siempre 0 para la posición del vértice, 1 para las coordenadas de la textura. Sin embargo, ten en cuenta que esto sólo se aplica a las entradas de vértice, y no es necesariamente cierto para las variables de salida del sombreador de vértices que luego se utilizan como entradas en el sombreador de fragmentos (normalmente, las coordenadas de textura interpoladas).

Los siguientes uniformes están predefinidos:

  • mat4 qt_Matrix - matriz de transformación combinada, el producto de las matrices del elemento raíz a este ShaderEffect, y una proyección ortogonal.
  • float qt_Opacity - opacidad combinada, el producto de las opacidades desde el elemento raíz hasta este ShaderEffect.

Nota: GLSL estilo Vulkan no tiene variables uniformes separadas. En su lugar, los shaders deben utilizar siempre un bloque uniforme con un punto de enlace de 0.

Nota: El calificador de disposición de bloque uniforme debe ser siempre std140.

Nota: A diferencia de las entradas de vértice, los nombres predefinidos (qt_Matrix, qt_Opacity) no deben cambiarse.

Además, cualquier propiedad que pueda asignarse a un tipo GLSL puede ponerse a disposición de los sombreadores. La siguiente lista muestra cómo se asignan las propiedades:

  • bool, int, qreal -> bool, int, float - Si el tipo en el shader no es el mismo que en QML, el valor se convierte automáticamente.
  • QColor -> vec4 - Cuando los colores se pasan al shader, primero se premultiplican. Así, por ejemplo, Qt.rgba(0.2, 0.6, 1.0, 0.5) se convierte en vec4(0.1, 0.3, 0.5, 0.5) en el shader.
  • QRect, QRectF -> vec4 - Qt.rect(x, y, w, h) se convierte en vec4(x, y, w, h) en el shader.
  • QPoint, QPointF, QSize, QSizeF -> vec2
  • QVector3D -> vec3
  • QVector4D -> vec4
  • QTransform -> mat3
  • QMatrix4x4 -> mat4
  • QQuaternion -> vec4, el valor escalar es w.
  • Image -> sampler2D - El origen está en la esquina superior izquierda, y los valores de color están premultiplicados. La textura se proporciona tal cual, excluyendo el fillMode del elemento Image. Para incluir fillMode, utilice ShaderEffectSource o Image::layer::enabled.
  • ShaderEffectSource -> sampler2D - El origen está en la esquina superior izquierda y los valores de color se premultiplican.

Los muestreadores se siguen declarando como variables uniformes separadas en el código del sombreador. Los sombreadores son libres de elegir cualquier punto de enlace para ellos, excepto 0 porque está reservado para el bloque uniforme.

Algunos lenguajes de sombreado y API tienen un concepto de objetos de imagen y muestreador separados. Qt Quick siempre trabaja con objetos de muestreador de imagen combinados en los sombreadores, tal y como admite SPIR-V. Por lo tanto, los sombreadores suministrados para ShaderEffect deben utilizar siempre declaraciones de muestreador del estilo de layout(binding = 1) uniform sampler2D tex;. La capa de abstracción subyacente y el shader pipeline se encargan de hacer que esto funcione para todas las APIs y lenguajes de sombreado soportados, de forma transparente para las aplicaciones.

El back-end del gráfico de escena QML puede elegir asignar texturas en atlas de texturas. Si una textura asignada en un atlas se pasa a un ShaderEffect, por defecto se copia desde el atlas de texturas a una textura independiente, de modo que las coordenadas de la textura abarcan de 0 a 1, y se obtienen los modos de envoltura esperados. Sin embargo, esto aumentará el uso de memoria. Para evitar la copia de la textura, establezca supportsAtlasTextures para shaders simples utilizando qt_MultiTexCoord0, o para cada "sampler2D uniforme <nombre>" declare un "vec4 uniforme qt_SubRect_<nombre>" al que se le asignará el rectángulo fuente normalizado de la textura. Para texturas independientes, el rectángulo fuente es [0, 1]x[0, 1]. Para las texturas en un atlas, el rectángulo de origen corresponde a la parte del atlas de textura donde se almacena la textura. La forma correcta de calcular la coordenada de textura para una textura llamada "fuente" dentro de un atlas de textura es "qt_SubRect_source.xy + qt_SubRect_source.zw * qt_MultiTexCoord0".

La salida de fragmentShader debe ser premultiplicada. Si blending está activado, se utiliza la mezcla de fuente sobre fuente. Sin embargo, la mezcla aditiva se puede lograr mediante la salida de cero en el canal alfa.

import QtQuick 2.0

Rectangle {
    width: 200; height: 100
    Row {
        Image { id: img;
                sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
        ShaderEffect {
            width: 100; height: 100
            property variant src: img
            vertexShader: "myeffect.vert.qsb"
            fragmentShader: "myeffect.frag.qsb"
        }
    }
}

El ejemplo asume que myeffect.vert y myeffect.frag contienen código GLSL estilo Vulkan, procesado por la herramienta qsb para generar los archivos .qsb.

#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTexCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}
#version 440
layout(location = 0) in vec2 coord;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D src;
void main() {
    vec4 tex = texture(src, coord);
    fragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
}

Nota: Las texturas de Scene Graph tienen el origen en la esquina superior izquierda en lugar de en la inferior izquierda, como es habitual en OpenGL.

Tener un solo sombreador

Especificar tanto vertexShader como fragmentShader no es obligatorio. Muchas implementaciones de ShaderEffect querrán proporcionar sólo un fragment shader en la práctica, mientras confían en el vertex shader por defecto.

El sombreador de vértices por defecto pasa la coordenada de la textura al sombreador de fragmentos como vec2 qt_TexCoord0 en la ubicación 0.

El sombreador de fragmentos por defecto espera que la coordenada de la textura sea pasada desde el sombreador de vértices como vec2 qt_TexCoord0 en la ubicación 0, y muestrea desde un sampler2D llamado source en el punto de enlace 1.

Advertencia: Cuando sólo se especifica uno de los shaders, el escritor del shader debe ser consciente de la disposición de bloques uniformes esperada por los shaders por defecto: qt_Matrix debe estar siempre en el offset 0, seguido de qt_Opacity en el offset 64. Cualquier uniforme personalizado debe colocarse después de qt_Matrix. Cualquier uniforme personalizado debe colocarse después de estos dos. Esto es obligatorio incluso cuando el sombreador proporcionado por la aplicación no utiliza la matriz o la opacidad, porque en tiempo de ejecución hay un único búfer uniforme que está expuesto tanto al sombreador de vértices como al de fragmentos.

Advertencia: A diferencia de lo que ocurre con las entradas de vértices, el paso de datos entre el sombreador de vértices y el de fragmentos puede requerir, en función de la API gráfica subyacente, que se utilicen los mismos nombres, no siendo siempre suficiente una ubicación coincidente. En particular, cuando se especifica un sombreador de fragmentos mientras se confía en el sombreador de vértices incorporado por defecto, las coordenadas de textura se pasan como qt_TexCoord0 en la ubicación 0, y por lo tanto se recomienda encarecidamente que el sombreador de fragmentos declare la entrada con el mismo nombre (qt_TexCoord0). No hacerlo puede dar lugar a problemas en algunas plataformas, por ejemplo, cuando se ejecuta con un contexto OpenGL de perfil no básico en el que el código fuente del sombreador GLSL subyacente no tiene calificadores de ubicación y la coincidencia se basa en los nombres de las variables durante el proceso de vinculación del sombreador.

ShaderEffect y capas de elementos

El tipo ShaderEffect puede combinarse con layered items.

Capa con efecto desactivado Capa con efecto activado
Item {
    id: layerRoot
    layer.enabled: true
    layer.effect: ShaderEffect {
       fragmentShader: "effect.frag.qsb"
    }
}
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D source;
void main() {
    vec4 p = texture(source, qt_TexCoord0);
    float g = dot(p.xyz, vec3(0.344, 0.5, 0.156));
    fragColor = vec4(g, g, g, p.a) * qt_Opacity;
}

También es posible combinar múltiples elementos en capas:

Rectangle {
    id: gradientRect;
    width: 10
    height: 10
    gradient: Gradient {
        GradientStop { position: 0; color: "white" }
        GradientStop { position: 1; color: "steelblue" }
    }
    visible: false; // should not be visible on screen.
    layer.enabled: true;
    layer.smooth: true
 }
 Text {
    id: textItem
    font.pixelSize: 48
    text: "Gradient Text"
    anchors.centerIn: parent
    layer.enabled: true
    // This item should be used as the 'mask'
    layer.samplerName: "maskSource"
    layer.effect: ShaderEffect {
        property var colorSource: gradientRect;
        fragmentShader: "mask.frag.qsb"
    }
}
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D colorSource;
layout(binding = 2) uniform sampler2D maskSource;
void main() {
    fragColor = texture(colorSource, qt_TexCoord0)
                    * texture(maskSource, qt_TexCoord0).a
                    * qt_Opacity;
}

Otras notas

Por defecto, el ShaderEffect consta de cuatro vértices, uno por cada esquina. Para transformaciones de vértices no lineales, como el page curl, puedes especificar una rejilla fina de vértices especificando una resolución mesh.

Migración desde Qt 5

Para aplicaciones Qt 5 con elementos ShaderEffect la migración a Qt 6 implica:

  • Mover el código de los shaders a archivos separados .vert y .frag,
  • actualizar los shaders a GLSL compatible con Vulkan,
  • ejecutar la herramienta qsb en ellos,
  • incluir los archivos .qsb resultantes en el ejecutable con el sistema de recursos Qt,
  • y hacer referencia al archivo en las propiedades vertexShader y fragmentShader.

Como se describe en el módulo Qt Shader Tools algunos de estos pasos pueden automatizarse dejando que CMake invoque la herramienta qsb en tiempo de compilación. Ver Qt Shader Tools Build System Integration para más información y ejemplos.

Cuando se trata de actualizar el código del shader, a continuación se muestra una visión general de los cambios comúnmente requeridos.

Sombreador de vértices en Qt 5Sombreador de vértices en Qt 6
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
varying highp vec2 coord;
uniform highp mat4 qt_Matrix;
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}
#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTexCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
void main() {
    coord = qt_MultiTexCoord0;
    gl_Position = qt_Matrix * qt_Vertex;
}

El proceso de conversión consiste principalmente en actualizar el código para que sea compatible con GL_KHR_vulkan_glsl. Vale la pena señalar que Qt Quick utiliza un subconjunto de las características proporcionadas por GLSL y Vulkan, y por lo tanto el proceso de conversión para shaders ShaderEffect típicos suele ser sencillo.

  • La directiva version debe indicar 440 o 450, aunque especificar otra versión de GLSL puede funcionar también, porque la extensión GL_KHR_vulkan_glsl está escrita para GLSL 140 y superiores.
  • Las entradas y salidas deben utilizar las palabras clave GLSL modernas in y out. Además, es necesario especificar una ubicación. Los espacios de nombres de las ubicaciones de entrada y salida son independientes, por lo que es seguro asignar ubicaciones que empiecen por 0 para ambas.
  • Cuando se trata de las entradas del sombreador de vértices, las únicas posibilidades con ShaderEffect son la ubicación 0 para la posición del vértice (tradicionalmente denominada qt_Vertex) y la ubicación 1 para las coordenadas de la textura (tradicionalmente denominada qt_MultiTexCoord0).
  • Las salidas del sombreador de vértices y las entradas del sombreador de fragmentos las define el código del sombreador. El fragment shader debe tener una salida vec4 en la posición 0 (normalmente llamada fragColor). Para obtener la máxima portabilidad, las salidas de vértice y las entradas de fragmento deben utilizar el mismo número de ubicación y el mismo nombre. Cuando se especifica sólo un sombreador de fragmentos, las coordenadas de textura se pasan desde el sombreador de vértices incorporado como vec2 qt_TexCoord0 en la ubicación 0, como se muestra en los fragmentos de ejemplo anteriores.
  • Las variables uniformes fuera de un bloque uniforme no son legales. Los datos uniformes deben declararse en un bloque uniforme con el punto de enlace 0.
  • Se espera que el bloque uniforme utilice el calificador std140.
  • En tiempo de ejecución, el sombreador de vértices y el de fragmentos obtendrán el mismo búfer uniforme ligado al punto de enlace 0. Por lo tanto, como regla general, las declaraciones del bloque uniforme deben ser idénticas entre los sombreadores. Esto también incluye los miembros que no se utilizan en uno de los shaders. Los nombres de los miembros deben coincidir, porque con algunas APIs gráficas el bloque uniforme se convierte en un struct uniforme tradicional, de forma transparente para la aplicación.
  • Cuando proporcione sólo uno de los sombreadores, tenga cuidado con el hecho de que los sombreadores incorporados esperan qt_Matrix y qt_Opacity en la parte superior del bloque uniforme. (Como regla general, inclúyelos siempre como primer y segundo miembro del bloque.
  • En el ejemplo, el bloque uniforme especifica el nombre de bloque buf. Este nombre puede cambiarse libremente, pero debe coincidir entre los shaders. El uso de un nombre de instancia, como layout(...) uniform buf { ... } instance_name;, es opcional. Cuando se especifica, todos los accesos a los miembros deben calificarse con instance_name.
Sombreador de fragmentos en Qt 5Sombreador de fragmentos en Qt 6
varying highp vec2 coord;
uniform lowp float qt_Opacity;
uniform sampler2D src;
void main() {
    lowp vec4 tex = texture2D(src, coord);
    gl_FragColor = vec4(vec3(dot(tex.rgb,
                        vec3(0.344, 0.5, 0.156))),
                             tex.a) * qt_Opacity;
}
#version 440
layout(location = 0) in vec2 coord;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
    float qt_Opacity;
};
layout(binding = 1) uniform sampler2D src;
void main() {
    vec4 tex = texture(src, coord);
    fragColor = vec4(vec3(dot(tex.rgb,
                     vec3(0.344, 0.5, 0.156))),
                          tex.a) * qt_Opacity;
}
  • Los calificadores de precisión (lowp, mediump, highp) no se utilizan actualmente.
  • Las llamadas a funciones GLSL integradas deben seguir los nombres GLSL modernos, principalmente texture() en lugar de texture2D().
  • Los muestreadores deben utilizar puntos de enlace a partir de 1.
  • Cuando Qt Quick está renderizando con multiview activado, por ejemplo porque es parte de una escena 3D renderizada en un entorno VR/AR donde el contenido de los ojos izquierdo y derecho se generan en una sola pasada, los shaders del ShaderEffect tienen que ser escritos teniendo esto en cuenta. Con un recuento de vistas de 2 por ejemplo, habrá 2 matrices (qt_Matrix es un array de mat4 con dos elementos). Se espera que el sombreador de vértices tenga en cuenta gl_ViewIndex. Consulta la sección Multiview del Manual QSB para obtener información general sobre la creación de sombreadores con capacidad multivista.

Véase también Item Layers, QSB Manual, y Qt Shader Tools Build System Integration.

Documentación de Propiedades

blending : bool

Si esta propiedad es verdadera, la salida de fragmentShader se mezcla con el fondo utilizando el modo de fusión fuente-sobrefondo. Si es false, se ignora el fondo. La mezcla disminuye el rendimiento, por lo que debe establecer esta propiedad a false cuando la mezcla no sea necesaria. El valor por defecto es true.

cullMode : enumeration

Esta propiedad define qué lados del elemento deben ser visibles.

ConstanteDescripción
ShaderEffect.NoCullingAmbos lados son visibles
ShaderEffect.BackFaceCullingSólo es visible la cara frontal
ShaderEffect.FrontFaceCullingsólo es visible la parte trasera

Por defecto es NoCulling.

fragmentShader : url

Esta propiedad contiene una referencia a un archivo con el paquete fragment shader preprocesado, normalmente con una extensión de .qsb. El valor se trata como un URL, de forma similar a otros tipos QML, como Image. Debe ser un archivo local o utilizar el esquema qrc para acceder a archivos incrustados a través del sistema de recursos de Qt. La URL puede ser absoluta o relativa a la URL del componente.

Atención: Los shaders, incluidos los archivos .qsb, se consideran contenido de confianza. Se recomienda a los desarrolladores de aplicaciones que consideren cuidadosamente las implicaciones potenciales antes de permitir la carga de contenido proporcionado por el usuario que no forme parte de la aplicación.

Véase también vertexShader.

log : string [read-only]

Esta propiedad contiene un registro de advertencias y errores del último intento de compilación de los shaders. Se actualiza al mismo tiempo que status se establece en Compilado o Error.

Nota: En Qt 6, el shader pipeline promueve la compilación y traducción de los shaders GLSL estilo Vulkan offline, o como muy tarde en tiempo de compilación. Esto no significa necesariamente que no haya compilación de shaders en tiempo de ejecución, pero incluso si la hay, ShaderEffect no está involucrado en ello, y los errores de sintaxis y similares no deberían ocurrir más en esa etapa. Por lo tanto, el valor de esta propiedad suele estar vacío.

Véase también status.

mesh : variant

Esta propiedad define la malla utilizada para dibujar el ShaderEffect. Puede contener cualquier objeto GridMesh. Si se asigna un valor de tamaño a esta propiedad, el ShaderEffect utiliza implícitamente un GridMesh con el valor como mesh resolution. Por defecto, esta propiedad tiene el tamaño 1x1.

Véase también GridMesh.

status : enumeration [read-only]

Esta propiedad indica el estado actual de los sombreadores.

ConstanteDescripción
ShaderEffect.Compiledel programa de sombreado ha sido compilado y enlazado correctamente.
ShaderEffect.Uncompiledel programa de sombreado aún no ha sido compilado.
ShaderEffect.Errorel programa de sombreado no ha podido ser compilado o enlazado.

Cuando se establece el código fuente del fragment o vertex shader, el estado pasará a ser Uncompiled. La primera vez que se renderiza ShaderEffect con un nuevo código fuente de shaders, éstos se compilan y enlazan, y el estado se actualiza a Compilado o Error.

Cuando no se utiliza la compilación en tiempo de ejecución y las propiedades del sombreador hacen referencia a archivos con código de bytes, el estado es siempre Compilado. El contenido del sombreador no se examina (aparte de la reflexión básica para descubrir los elementos de entrada de vértices y los datos del búfer de constantes) hasta más adelante en el proceso de renderizado, por lo que los posibles errores (como el diseño o la falta de coincidencia de la firma raíz) sólo se detectarán en un momento posterior.

Véase también log.

supportsAtlasTextures : bool [since QtQuick 2.4]

Establece esta propiedad como true para confirmar que tu código de sombreado no depende de qt_MultiTexCoord0 que va de (0,0) a (1,1) relativo a la malla. En este caso el rango de qt_MultiTexCoord0 se basará en la posición de la textura dentro del atlas. Esta propiedad actualmente no tiene efecto si hay menos, o más, de un sampler uniforme usado como entrada a tu shader.

Esto difiere de proporcionar qt_SubRect_<nombre> uniformes en que este último permite dibujar una o más texturas del atlas en un solo elemento ShaderEffect, mientras que supportsAtlasTextures permite múltiples instancias de un componente ShaderEffect utilizando una imagen de origen diferente del atlas para ser por lotes en un solo dibujo. Ambos evitan que una textura sea copiada fuera del atlas cuando es referenciada por un ShaderEffect.

El valor por defecto es false.

Esta propiedad se introdujo en QtQuick 2.4.

vertexShader : url

Esta propiedad contiene una referencia a un archivo con el paquete de sombreado de vértices preprocesado, normalmente con una extensión de .qsb. El valor se trata como un URL, de forma similar a otros tipos de QML, como Image. Debe ser un archivo local o utilizar el esquema qrc para acceder a archivos incrustados a través del sistema de recursos de Qt. La URL puede ser absoluta o relativa a la URL del componente.

Atención: Los shaders, incluidos los archivos .qsb, se consideran contenido de confianza. Se recomienda a los desarrolladores de aplicaciones que consideren cuidadosamente las implicaciones potenciales antes de permitir la carga de contenido proporcionado por el usuario que no forme parte de la aplicación.

Véase también fragmentShader.

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