Dibujo Qt 2D: dibujar texto, ruta, imagen, modo compuesto

1. Dibujar texto

Además de dibujar gráficos, también puede usar la función QPainter::darwText() para dibujar texto, o usar QPainter::setFont() para establecer la fuente utilizada por el texto, y usar la función QPainter::fontInfo() para obtener información de fuente, que devuelve un objeto de clase QFontInfo. El suavizado se usa de forma predeterminada al dibujar texto.

1.1 Dibujo básico

La demostración del código aún se realiza en el programa de la sección anterior, y el contenido de paintEvent() se cambia de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{    
      QPainter painter(this);    
      painter.drawText(100, 100,  "qter.org-yafeilinux");
}

Esto dibuja una cadena en la posición (100, 100). Resultados como se muestra a continuación.

 Los beneficios de este artículo, la tarifa para recibir el paquete de materiales de aprendizaje de desarrollo Qt, video técnico, el contenido incluye (base del lenguaje C++, introducción a la programación Qt, mecanismo de ranura y señal QT, dibujo de imagen de desarrollo de interfaz QT, red QT, programación de base de datos QT, combate de proyecto QT, QSS, OpenCV, módulo rápido, preguntas de entrevista, etc.) ↓↓↓↓↓↓ Ver a continuación

1.2 Posición del texto de control

Primero vamos a la página de documentación de ayuda de QPainter, luego miramos la forma sobrecargada de la función drawText() y encontramos:

QPainter::drawText ( const QRectF & rectangle, int flags, const QString & text, QRectF * boundingRect = 0 )
  • El primer parámetro especifica el rectángulo donde se dibuja el texto;
  • El segundo parámetro especifica la alineación del texto en el rectángulo, que está definida por el tipo de enumeración Qt::AlignmentFlag. También se pueden usar diferentes alineaciones al mismo tiempo usando el operador "|". También se pueden usar aquí otras banderas definidas por Qt::TextFlag, como ajuste de línea automático, etc.;
  • El tercer parámetro es el texto a dibujar, aquí puedes usar "\n" para lograr el salto de línea;
  • Por lo general, no es necesario configurar el cuarto parámetro.

Veamos un ejemplo. Para ver más claramente la posición del texto en el rectángulo especificado, dibujamos este rectángulo. Cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //设置一个矩形
    QRectF rect(50, 50, 300, 200);
    //为了更直观地看到字体的位置,我们绘制出这个矩形
    painter.drawRect(rect);
    painter.setPen(QColor(Qt::red));
    //这里先让字体水平居中
    painter.drawText(rect, Qt::AlignHCenter, "yafeilinux");
}

Ahora ejecute el programa, el efecto se muestra en la siguiente figura.

 

Las alineaciones disponibles se muestran en la siguiente imagen.

 

1.3 Uso de fuentes

Para dibujar un texto hermoso, puede usar la clase QFont para establecer la fuente del texto. También puede consultar primero la introducción de esta clase en la documentación de ayuda. Algunas de las configuraciones más utilizadas se muestran a continuación.

Cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //设置一个矩形
    QRectF rect(50, 50, 300, 200);
    //为了更直观地看到字体的位置,我们绘制出这个矩形
    painter.drawRect(rect);
    painter.setPen(QColor(Qt::red));
    //这里先让字体水平居中
    painter.drawText(rect, Qt::AlignHCenter, "yafeilinux");

    //使用字体
    QFont font("宋体", 15, QFont::Bold, true);
    //设置下划线
    font.setUnderline(true);
    //设置上划线
    font.setOverline(true);
    //设置字母大小写
    font.setCapitalization(QFont::SmallCaps);
    //设置字符间的间距
    font.setLetterSpacing(QFont::AbsoluteSpacing, 10);
    //使用字体
    painter.setFont(font);
    painter.setPen(Qt::blue);
    painter.drawText(120, 80, tr("yafeilinux"));
    painter.translate(50, 50);
    painter.rotate(90);
    painter.drawText(0, 0, tr("helloqt"));
}

Aquí se crea un objeto de fuente QFont, y el constructor utilizado es QFont::QFont ( const QString & family, int pointSize = -1, int weight = -1, bool italic = false ), el primer parámetro establece el atributo de familia de la fuente, la familia de fuentes utilizada aquí es Arial, y puede usar la clase QFontDatabase para obtener todas las fuentes admitidas; el segundo parámetro es el tamaño en puntos, y el tamaño predeterminado es 12; el tercer parámetro es el peso atributo, que se usa aquí en negrita; la última propiedad establece si se usa cursiva. Luego usamos varias otras funciones para formatear la fuente, y finalmente llamamos a la función setFont() para usar la fuente, y usamos otra forma sobrecargada de la función drawText() para dibujar el texto en el punto (120, 80). Posteriormente, el sistema de coordenadas fue trasladado y rotado, y luego el texto fue dibujado nuevamente. Ejecute el programa, el efecto se muestra en la siguiente figura.

 

2. Dibujar el camino

Si desea dibujar un gráfico complejo, puede usar la clase QPainterPath y luego usar QPainter::drawPath() para dibujar. La clase QPainterPath proporciona un contenedor para operaciones de dibujo que se puede usar para crear gráficos y reutilizarlos. Un trazado de dibujo es un objeto compuesto por varios rectángulos, elipses, líneas o curvas. Un trazado puede ser cerrado, como rectángulos y elipses, o abierto, como líneas y curvas.

2.1 Aplicación sencilla

Veamos un ejemplo: agregue una elipse y una línea en la ruta de gráficos. Todavía explicado en el proyecto anterior. Cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    //添加一个椭圆和一根线在图形路径里
    QPainterPath path;
    path.addEllipse(100, 100, 50, 50); //添加一个圆心为(100,100),横纵半径都为50的椭圆
    path.lineTo(200, 200); //添加一根从当前位置到(200,200)的线
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::red);
    painter.drawPath(path);
}

Después de crear un objeto QPainterPath, puede usar funciones como lineTo(), arcTo(), cubicTo() y quadTo() para agregar líneas o curvas a la ruta. Ejecute el programa, el efecto se muestra en la siguiente figura.

 

2.2 Copiar gráficos

Si simplemente une varios gráficos juntos, no hay necesidad de usar rutas en absoluto.La razón por la que se introducen las rutas es debido a una función muy útil: copiar rutas de gráficos. Cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    //添加一个椭圆和一根线在路径里
    QPainterPath path;
    path.addEllipse(100, 100, 50, 50); //添加一个圆心为(100,100),横纵半径都为50的椭圆
    path.lineTo(200, 200); //添加一根从当前位置到(200,200)的线
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::red);
    painter.drawPath(path);

    //复制图形路径
    QPainterPath path2;
    path2.addPath(path);
    path2.translate(100,0);
    painter.drawPath(path2);
}

Ahora ejecute el programa, el efecto se muestra en la siguiente figura.

 

Se puede ver que para el camino ya trazado, es muy sencillo repetir el dibujo.

2.3 Posición actual al dibujar gráficos

Primero veamos un ejemplo, cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    QPainterPath path;
    path.lineTo(100, 100);
    path.lineTo(200, 100);
    QPainter painter(this);
    painter.drawPath(path);
}

El efecto de ejecución del programa se muestra en la siguiente figura.

 

Se puede ver que después de crear la ruta, el valor predeterminado es dibujar desde el punto (0, 0). Después de dibujar la primera línea recta, la posición actual es el punto (100, 100), y la segunda línea recta se dibuja desde aquí. Después de dibujar la segunda línea, la posición actual es (200, 100).

También podemos usar la función moveTo() para cambiar la posición del punto actual. Por ejemplo, cambie la función paintEvent() de la siguiente manera:

void Widget::paintEvent(QPaintEvent *)
{
    QPainterPath path;
    path.addRect(50, 50, 40, 40);

    //移动到(100, 100)点
    path.moveTo(100, 100);

    path.lineTo(200, 200);
    QPainter painter(this);
    painter.drawPath(path);
}

De esta forma, cuando se dibuje el rectángulo, se desplazará al punto (100, 100) para su posterior dibujo. El efecto de ejecución del programa se muestra en la siguiente figura.

 

3. Haz dibujos

Qt proporciona cuatro clases para manejar datos de imagen: QImage, QPixmap, QBitmap y QPicture, que son dispositivos de dibujo de uso común. Entre ellos, QImage se usa principalmente para el procesamiento de E/S, lo que optimiza las operaciones de procesamiento de E/S y se puede usar para acceder y manipular píxeles directamente; QPixmap se usa principalmente para mostrar imágenes en la pantalla, lo que optimiza las imágenes que se muestran en la pantalla; QBitmap es una subclase de QPixmap, que se usa para procesar imágenes con una profundidad de color de 1, es decir, solo se pueden mostrar colores en blanco y negro; QPicture se usa para grabar y reproducir comandos de QPainter. En esta sección solo explicamos QPixmap.

3.1 Dibujo simple de imágenes

(1) Esta vez recreamos una aplicación Qt Widgets, el nombre del proyecto es mypixmap, en la página de información de la clase, seleccionamos la clase base como QDialog y usamos el Diálogo predeterminado como el nombre de la clase.

(2) Luego copie una imagen en el directorio del código fuente, por ejemplo, aquí hay una imagen logo.png, como se muestra en la figura a continuación.

 

(3) Agregue la declaración de la función del controlador de eventos de redibujado en el archivo dialog.h:

protected:
    void paintEvent(QPaintEvent *);

(4) Primero agregue el archivo de encabezado al archivo dialog.cpp para incluir #include <QPainter>, y luego agregue la definición de la función:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("../mypixmap/logo.png");
    painter.drawPixmap(0, 0, 80, 100, pix);
}

Aquí se usa una ruta relativa, porque Qt Creator usa shadow build de forma predeterminada, es decir, los archivos compilados están en un directorio como build-mypixmap-Desktop_Qt_5_8_0_MinGW_32bit-Debug, y este directorio es el directorio actual, por lo que el directorio del código fuente es su directorio principal. Puede cambiar la ruta según su situación real o usar una ruta absoluta, pero es mejor usar archivos de recursos para almacenar imágenes. La función drawPixmap() dibuja una imagen en un rectángulo dado, donde la esquina superior izquierda del rectángulo es (0, 0), con un ancho de 80 y una altura de 100. Si el ancho y la altura son diferentes del tamaño de la imagen, la imagen se estirará de manera predeterminada. El efecto de funcionamiento se muestra en la siguiente figura.

 

3.2 Imagen panorámica

La función translate() en la clase QPainter realiza el cambio del origen de coordenadas, después de cambiar el origen, este punto se convertirá en el nuevo origen (0, 0). Veamos un ejemplo. Continúe agregando el siguiente código en la función paintEvent():

//将(100,100)设为坐标原点
painter.translate(100, 100);
painter.drawPixmap(0, 0, 80, 100, pix);

Aquí, (100, 100) se establece como el nuevo origen de coordenadas, por lo que la siguiente textura en (0, 0) es equivalente a la textura anterior (100, 100). Ejecute el programa, el efecto se muestra en la siguiente figura.

 

3.3 Ampliar imagen

Podemos usar la función scaled() en la clase QPixmap para acercar y alejar la imagen. Continúe agregando el siguiente código en la función paintEvent():

//获得以前图片的宽和高
qreal width = pix.width();
qreal height = pix.height();
//将图片的宽和高都缩小,并且在给定的矩形内保持宽高的比值不变
pix = pix.scaled(width, height,Qt::KeepAspectRatio);
painter.drawPixmap(90, 90, pix);

Entre ellos, el parámetro Qt::KeepAspectRatio es la forma de hacer zoom en la imagen. Puede colocar el puntero del mouse sobre el código y presionar la tecla F1 para ver su ayuda, como se muestra en la figura a continuación.

 

Hay tres valores aquí, que pueden entenderse aproximadamente mirando la imagen de ejemplo. Qt::IgnoreAspectRatio no mantiene la relación de aspecto de la imagen; Qt::KeepAspectRatio mantiene la relación de aspecto en un rectángulo dado; el último también mantiene la relación de aspecto, pero puede exceder el rectángulo dado. El rectángulo dado aquí está determinado por los parámetros dados cuando mostramos la imagen, por ejemplo, pintor.drawPixmap(0,0,100,100,pix); está en un rectángulo cuyo ancho y alto son 100 a partir del punto (0,0). El efecto de ejecutar el programa se muestra en la siguiente figura.

 

3.4 Rotar imagen

La rotación utiliza la función de rotación () de la clase QPainter, que gira alrededor del origen de forma predeterminada. Si desea cambiar el centro de rotación, puede usar la función translate() mencionada anteriormente. Continúe agregando el siguiente código en la función paintEvent():

//让图片的中心作为旋转的中心
painter.translate(40, 50);
painter.rotate(90); //顺时针旋转90度
painter.translate(-40,-50); //使原点复原
painter.drawPixmap(100, 100, 80, 100, pix);

Aquí primero debe cambiar el centro de rotación, luego rotar y luego restaurar el origen para lograr el efecto deseado. Ejecute el programa, como se muestra en la siguiente figura.

 

3.5 Imágenes distorsionadas

La distorsión de la imagen se logra usando la función shear(qreal sh, qreal sv) de la clase QPainter. Tiene dos parámetros, el primer parámetro realiza la deformación horizontal y el último parámetro realiza la deformación longitudinal. Cuando su valor es 0, significa que no hay distorsión. Continúe agregando el siguiente código en paintEvent():

painter.shear(0.5, 0); //横向扭曲
painter.drawPixmap(100, 0, 80, 100, pix);

El efecto de funcionamiento se muestra en la siguiente figura.

 

4. Modo compuesto

QPainter proporciona modos de composición para definir cómo completar la composición de imágenes digitales, es decir, cómo combinar los píxeles de la imagen de origen y los píxeles de la imagen de destino. Los modos compuestos comúnmente utilizados y sus efectos proporcionados por QPainter se muestran en la siguiente figura. El tipo común es SoiirceOver (generalmente llamado combinación alfa), es decir, el píxel de origen que se dibuja se mezcla con el píxel de destino que se ha dibujado, y el componente alfa del píxel de origen define su transparencia, de modo que la imagen de origen se mostrará en la imagen de destino con un efecto transparente. Cuando se establece el modo compuesto, se aplicará a todas las operaciones de dibujo, como lápiz, pincel, degradado y dibujo de mapa de píxeles/imagen, etc.

 

 

Ejemplo:

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    QImage image(400, 300, QImage::Format_ARGB32_Premultiplied);
    painter.begin(&image);
    painter.setBrush(Qt::green);
    painter.drawRect(100, 50, 200, 200);
    painter.setBrush(QColor(0, 0, 255, 150));
    painter.drawRect(50, 0, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    painter.drawRect(250, 0, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
    painter.drawRect(50, 200, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_Xor);
    painter.drawRect(250, 200, 100, 100);
    painter.end();
    painter.begin(this);
    painter.drawImage(0, 0, image);
}

Aquí, primero se dibuja un rectángulo en Qlmage, y luego se dibujan 4 rectángulos pequeños en las esquinas del rectángulo 4. Cada rectángulo pequeño usa un modo compuesto diferente y se rellena con un color translúcido. El primer rectángulo pequeño no especifica explícitamente el modo compuesto, utiliza el modo SourceOver de forma predeterminada. El efecto de funcionamiento se muestra en la siguiente figura.

 

El artículo se transfiere desde el jardín del blog (fengMisaka): Qt 2D dibujo tres: dibujar texto, ruta, imagen, modo compuesto

Los beneficios de este artículo, la tarifa para recibir el paquete de materiales de aprendizaje de desarrollo Qt, video técnico, el contenido incluye (base del lenguaje C++, introducción a la programación Qt, mecanismo de ranura y señal QT, dibujo de imagen de desarrollo de interfaz QT, red QT, programación de base de datos QT, combate de proyecto QT, QSS, OpenCV, módulo rápido, preguntas de entrevista, etc.) ↓↓↓↓↓↓ Ver a continuación

Supongo que te gusta

Origin blog.csdn.net/QtCompany/article/details/131838628
Recomendado
Clasificación