[100 días competentes en python] Día 39: programación de la interfaz GUI_PyQt desde la entrada hasta el combate real (abajo)_dibujo gráfico y efectos de animación, visualización de datos, interacción de actualización

Tabla de contenido

Guía de columna 

6 efectos gráficos de dibujo y animación

6.1 Dibujar gráficos, texto e imágenes básicos

6.2 Realizar efectos de animación y efectos de transición

7 Visualización de datos

7.1 Dibujar gráficos con Matplotlib

7.2 Dibujar gráficos usando PyQtGraph

7.3 Actualización en tiempo real y operación interactiva de datos

7.3.1 Actualización de datos en tiempo real

7.3.2 Interacción

7.4 Componentes de visualización de datos personalizados  


Guía de columna 

Dirección de suscripción de columna: https://blog.csdn.net/qq_35831906/category_12375510.html


6 efectos gráficos de dibujo y animación

6.1 Dibujar gráficos, texto e imágenes básicos

En PyQt6, puede usar QPainter para operaciones de dibujo de gráficos. Aquí hay un ejemplo que muestra cómo dibujar gráficos básicos, texto e imágenes en la ventana:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtGui import QPainter, QPixmap, QColor, QPen
from PyQt6.QtCore import Qt

class DrawingWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Drawing Example")
        self.setGeometry(100, 100, 600, 400)

    def paintEvent(self, event):
        try:
            painter = QPainter(self)
            painter.setRenderHint(QPainter.RenderHint.Antialiasing)  # 修正此处

            # 绘制矩形
            painter.setBrush(QColor(255, 0, 0))
            painter.drawRect(50, 50, 100, 100)

            # 绘制椭圆
            painter.setBrush(QColor(0, 255, 0))
            painter.drawEllipse(200, 50, 100, 100)

            # 绘制文本
            painter.setPen(QPen(QColor(0, 0, 255)))
            painter.setFont(self.font())  # 使用默认字体
            painter.drawText(50, 200, "Hello, PyQt!")

            # 绘制图片,并使其自适应窗口
            pixmap = QPixmap("image.png")
            if not pixmap.isNull():
                scaled_pixmap = pixmap.scaled(self.width() // 2, self.height() // 2, Qt.AspectRatioMode.KeepAspectRatio)
                x = (self.width() - scaled_pixmap.width())
                y = (self.height() - scaled_pixmap.height()) 
                painter.drawPixmap(x, y, scaled_pixmap)

        except Exception as e:
            print("An error occurred during painting:", str(e))

    def resizeEvent(self, event):
        # 在窗口大小改变时重新绘制
        self.update()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = DrawingWindow()
    window.show()
    sys.exit(app.exec())

 producción:

6.2 Realizar efectos de animación y efectos de transición

        Para lograr efectos de animación y efectos de transición, puede usar QTimer para actualizar regularmente la interfaz para lograr cambios suaves en los gráficos. Aquí hay un ejemplo simple que muestra cómo usar QTimer para lograr un efecto de transición simple y suave:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton
from PyQt6.QtCore import QTimer, QRect, QPropertyAnimation
from PyQt6.QtGui import QPainter, QColor, QPen, QBrush
from PyQt6.QtCore import QVariantAnimation


class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Animation Example")
        self.setGeometry(100, 100, 400, 300)

        self.button = QPushButton("Animate", self)
        self.button.setGeometry(150, 150, 100, 30)
        self.button.clicked.connect(self.start_animation)

        # 初始位置和颜色
        self.rect = QRect(50, 50, 100, 100)
        self.rect_color = QColor(0, 0, 255)  # 初始颜色

        self.ellipse = QRect(250, 150, 100, 100)
        self.ellipse_color = QColor(0, 255, 0)  # 初始颜色

        # 颜色动画
        self.color_animation_rect = QVariantAnimation()
        self.color_animation_rect.valueChanged.connect(self.update_color_rect)
        self.color_animation_rect.setDuration(2000)  # 2秒的动画
        self.color_animation_rect.setStartValue(QColor(255, 0, 0))
        self.color_animation_rect.setEndValue(QColor(0, 0, 255))

        self.color_animation_ellipse = QVariantAnimation()
        self.color_animation_ellipse.valueChanged.connect(self.update_color_ellipse)
        self.color_animation_ellipse.setDuration(2000)  # 2秒的动画
        self.color_animation_ellipse.setStartValue(QColor(0, 255, 0))
        self.color_animation_ellipse.setEndValue(QColor(0, 0, 255))

        self.animation_timer = QTimer()
        self.animation_timer.timeout.connect(self.animate)

    def start_animation(self):
        self.animation_timer.start(10)
        self.color_animation_rect.start()
        self.color_animation_ellipse.start()

    def animate(self):
        try:
            # 移动矩形
            if self.rect.x() < 250:
                self.rect.translate(1, 0)
            else:
                self.animation_timer.stop()

            # 移动椭圆
            if self.ellipse.x() > 50:
                self.ellipse.translate(-1, 0)
        except Exception as e:
            print("An error occurred during animation:", str(e))

        self.update()

    def update_color_rect(self, color):
        self.rect_color = color

    def update_color_ellipse(self, color):
        self.ellipse_color = color

    def paintEvent(self, event):
        try:
            painter = QPainter(self)

            # 绘制实心矩形
            brush_rect = QBrush(self.rect_color)
            painter.setBrush(brush_rect)
            painter.drawRect(self.rect)

            # 绘制实心椭圆
            brush_ellipse = QBrush(self.ellipse_color)
            painter.setBrush(brush_ellipse)
            painter.drawEllipse(self.ellipse)
        except Exception as e:
            print("An error occurred during painting:", str(e))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec())

7 Visualización de datos

        La visualización de datos consiste en transformar los datos en elementos visuales, como tablas y gráficos, para comprender y analizar los datos de manera más intuitiva. En PyQt, puede usar bibliotecas de terceros como Matplotlib y PyQtGraph para dibujar gráficos y realizar la visualización de datos. Aquí están los detalles y ejemplos:

7.1 Dibujar gráficos con Matplotlib

        Matplotlib es una poderosa biblioteca de visualización de datos que puede crear varios tipos de gráficos, incluidos gráficos de líneas, diagramas de dispersión, histogramas y más.

Aquí hay un ejemplo de cómo dibujar un gráfico de líneas simple en una ventana de PyQt usando Matplotlib:

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Matplotlib 示例")  # 设置窗口标题
        self.setGeometry(100, 100, 800, 600)  # 设置窗口位置和大小

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)

        layout = QVBoxLayout()  # 创建垂直布局
        main_widget.setLayout(layout)

        fig, ax = plt.subplots()  # 创建 Matplotlib 图形和轴对象
        canvas = FigureCanvas(fig)  # 将图形对象放入 Matplotlib 画布中
        layout.addWidget(canvas)  # 将画布添加到布局中

        x = [1, 2, 3, 4, 5]
        y = [10, 25, 18, 35, 30]
        ax.plot(x, y)  # 在轴上绘制折线图

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = MyWindow()  # 创建自定义窗口对象
    window.show()  # 显示窗口
    sys.exit(app.exec())  # 运行应用程序事件循环

7.2 Dibujar gráficos usando PyQtGraph

        PyQtGraph es una biblioteca enfocada en la visualización de datos en tiempo real, adecuada para escenarios que necesitan mostrar grandes cantidades de datos rápidamente.

Este es un ejemplo del uso de PyQtGraph para dibujar un gráfico en tiempo real en una ventana de PyQt:

import sys
import numpy as np
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
import pyqtgraph as pg

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQtGraph 示例")  # 设置窗口标题
        self.setGeometry(100, 100, 800, 600)  # 设置窗口位置和大小

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)

        layout = QVBoxLayout()  # 创建垂直布局
        main_widget.setLayout(layout)

        self.plot_widget = pg.PlotWidget()  # 创建 PyQtGraph 绘图部件
        layout.addWidget(self.plot_widget)  # 将绘图部件添加到布局中

        self.data = np.random.normal(size=100)  # 创建随机数据数组
        self.curve = self.plot_widget.plot(self.data)  # 在绘图部件上绘制曲线

    def update_plot(self):
        self.data[:-1] = self.data[1:]  # 将数据向前移动一位
        self.data[-1] = np.random.normal()  # 生成新的随机数据
        self.curve.setData(self.data)  # 更新绘图曲线的数据

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = MyWindow()  # 创建自定义窗口对象
    window.show()  # 显示窗口

    timer = pg.QtCore.QTimer()  # 创建定时器对象
    timer.timeout.connect(window.update_plot)  # 连接定时器的超时信号和更新绘图函数
    timer.start(100)  # 每100毫秒触发一次定时器超时信号,更新绘图

    sys.exit(app.exec())  # 运行应用程序事件循环

7.3 Actualización en tiempo real y operación interactiva de datos

        Para lograr una actualización de datos en tiempo real, se puede usar un temporizador para actualizar periódicamente el gráfico. En el ejemplo anterior de PyQtGraph, update_plotla actualización en tiempo real se logra creando un temporizador y conectándolo al método.

        La actualización en tiempo real y la operación interactiva de los datos es una parte importante de la visualización de datos, que permite a los usuarios observar los cambios en los datos e interactuar con los datos de manera más intuitiva. Esta sección explicará en detalle cómo implementar la actualización de datos en tiempo real y algunas operaciones interactivas comunes en PyQt.

7.3.1 Actualización de datos en tiempo real

        En la visualización de datos, la actualización en tiempo real generalmente requiere el uso de temporizadores para actualizar periódicamente la visualización de un cuadro o gráfico. En PyQt, puede usar QTimerpara implementar la actualización de tiempo.

El siguiente es un ejemplo que muestra cómo implementar datos en tiempo real en un gráfico de Matplotlib

import sys
import random
import matplotlib.pyplot as plt
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from PyQt6.QtCore import QTimer

class RealTimePlotWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("实时绘图示例")  # 设置窗口标题
        self.setGeometry(100, 100, 800, 600)  # 设置窗口位置和大小

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)

        layout = QVBoxLayout()  # 创建垂直布局
        main_widget.setLayout(layout)

        self.fig, self.ax = plt.subplots()  # 创建 Matplotlib 图形和轴对象
        self.canvas = FigureCanvas(self.fig)  # 将图形对象放入 Matplotlib 画布中
        layout.addWidget(self.canvas)  # 将画布添加到布局中

        self.data = []  # 存储数据
        self.x_values = []  # 存储 x 值
        self.line, = self.ax.plot(self.x_values, self.data)  # 创建初始曲线对象
        self.timer = QTimer(self)  # 创建定时器对象
        self.timer.timeout.connect(self.update_plot)  # 连接定时器的超时信号和更新绘图函数
        self.timer.start(1000)  # 每秒触发一次定时器超时信号

    def update_plot(self):
        new_data = random.randint(0, 100)  # 生成新的随机数据
        self.data.append(new_data)  # 将新数据添加到数据列表中
        self.x_values.append(len(self.data))  # 添加对应的 x 值
        self.line.set_xdata(self.x_values)  # 更新曲线的 x 值
        self.line.set_ydata(self.data)  # 更新曲线的 y 值
        self.ax.relim()  # 重新计算坐标轴限制
        self.ax.autoscale_view()  # 自动调整坐标轴范围
        self.canvas.draw()  # 重新绘制画布

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = RealTimePlotWindow()  # 创建实时绘图窗口对象
    window.show()  # 显示窗口
    sys.exit(app.exec())  # 运行应用程序事件循环

7.3.2 Interacción

        En la visualización de datos, los usuarios pueden interactuar con un cuadro o gráfico a través de operaciones interactivas, como hacer zoom, desplazarse, pasar el mouse para mostrar puntos de datos, etc. Tanto Matplotlib como PyQtGraph proporcionan ricas funciones interactivas.

Aquí hay un ejemplo del uso de Matplotlib para mostrar puntos de datos al pasar el mouse:

import sys
import matplotlib.pyplot as plt
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

class InteractivePlotWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("交互式绘图示例")  # 设置窗口标题
        self.setGeometry(100, 100, 800, 600)  # 设置窗口位置和大小

        main_widget = QWidget(self)
        self.setCentralWidget(main_widget)

        layout = QVBoxLayout()  # 创建垂直布局
        main_widget.setLayout(layout)

        self.fig, self.ax = plt.subplots()  # 创建 Matplotlib 图形和轴对象
        self.canvas = FigureCanvas(self.fig)  # 将图形对象放入 Matplotlib 画布中
        layout.addWidget(self.canvas)  # 将画布添加到布局中

        self.data = [1, 2, 3, 4, 5]
        self.x_values = [1, 2, 3, 4, 5]
        self.line, = self.ax.plot(self.x_values, self.data)  # 创建初始曲线对象

        self.cid = self.fig.canvas.mpl_connect("motion_notify_event", self.on_hover)  # 连接鼠标移动事件和悬停函数

    def on_hover(self, event):
        if event.inaxes == self.ax:  # 如果鼠标位于图形轴上
            x, y = event.xdata, event.ydata  # 获取鼠标位置的数据坐标
            self.ax.set_title(f"悬停于点 ({x:.2f}, {y:.2f})")  # 设置标题显示鼠标位置
            self.canvas.draw()  # 重新绘制画布以更新标题显示

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = InteractivePlotWindow()  # 创建交互式绘图窗口对象
    window.show()  # 显示窗口
    sys.exit(app.exec())  # 运行应用程序事件循环

En este ejemplo, cuando el mouse pasa sobre el gráfico, las coordenadas del punto de datos sobre el que se encuentra el mouse se muestran en el título del gráfico.

        En resumen, realizar una actualización en tiempo real y una operación interactiva de los datos puede mejorar el efecto de la visualización de datos y permitir que los usuarios interactúen mejor con los datos. En PyQt, la actualización de datos en tiempo real se puede realizar usando el temporizador y la función de procesamiento de eventos correspondiente, y se pueden realizar varias operaciones interactivas usando la función de procesamiento de eventos.

7.4 Componentes de visualización de datos personalizados  

         En PyQt, puede personalizar los componentes de visualización de datos para satisfacer necesidades específicas, que pueden incluir cuadros, gráficos, áreas de dibujo personalizados, etc. Los componentes de visualización de datos personalizados le permiten crear estilos, funciones e interacciones específicos en función de los requisitos de su aplicación. A continuación se muestra un ejemplo simple que muestra cómo crear componentes de visualización de datos personalizados en PyQt.

import sys
import random
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
from PyQt6.QtCore import Qt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt

class CustomVisualization(QWidget):
    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()  # 创建垂直布局
        self.setLayout(layout)

        self.fig, self.ax = plt.subplots()  # 创建 Matplotlib 图形和轴对象
        self.canvas = FigureCanvas(self.fig)  # 将图形对象放入 Matplotlib 画布中
        layout.addWidget(self.canvas)  # 将画布添加到布局中

        self.data = [random.randint(0, 100) for _ in range(10)]  # 随机数据
        self.x_values = list(range(1, 11))  # x 值
        self.line, = self.ax.plot(self.x_values, self.data)  # 创建初始曲线对象

    def update_data(self):
        self.data = [random.randint(0, 100) for _ in range(10)]  # 生成新的随机数据
        self.line.set_ydata(self.data)  # 更新曲线的 y 值
        self.ax.relim()  # 重新计算坐标轴限制
        self.ax.autoscale_view()  # 自动调整坐标轴范围
        self.canvas.draw()  # 重新绘制画布

class CustomVisualizationWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("自定义可视化示例")  # 设置窗口标题
        self.setGeometry(100, 100, 800, 600)  # 设置窗口位置和大小

        self.custom_viz = CustomVisualization()  # 创建自定义可视化部件
        self.setCentralWidget(self.custom_viz)  # 将部件设置为中心部件

        self.timer = None

    def start_timer(self):
        if self.timer is None:
            self.timer = self.startTimer(1000)  # 创建定时器并每秒触发一次

    def timerEvent(self, event):
        self.custom_viz.update_data()  # 在定时器触发时更新数据

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建应用程序对象
    window = CustomVisualizationWindow()  # 创建自定义可视化窗口对象
    window.show()  # 显示窗口
    window.start_timer()  # 启动定时器
    sys.exit(app.exec())  # 运行应用程序事件循环

        Este ejemplo crea un componente de visualización de datos personalizado CustomVisualizationque usa Matplotlib para dibujar un gráfico de líneas en una ventana de PyQt. A través del temporizador, los datos se pueden actualizar periódicamente y se puede realizar la actualización en tiempo real de los datos. Puede ampliar los componentes visuales personalizados según sus necesidades, añadiendo funciones interactivas, estilos personalizados, etc.

Supongo que te gusta

Origin blog.csdn.net/qq_35831906/article/details/132338924
Recomendado
Clasificación