news 2026/5/19 2:44:08

Charts Factory 鼠标悬停显示数值信息实现详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Charts Factory 鼠标悬停显示数值信息实现详解

Charts Factory 鼠标悬停显示数值信息实现详解

charts_factory.py中,鼠标悬停显示数值信息的功能通过 PySide6 的信号槽机制和工具提示系统实现。以下是详细的实现原理和流程:

1. 核心实现机制

1.1 信号连接机制

在创建每种图表类型时,都会将图表系列的hovered信号连接到对应的处理函数:

# 折线图信号连接(line_chart.py:102)series.hovered.connect(self.on_line_hovered)# 柱状图信号连接(bar_chart.py:208) - 使用lambda传递额外参数bar_set.hovered.connect(lambdastatus,index,bs=bar_set:self.on_bar_hovered(status,index,bs))

1.2 事件处理函数

每种图表类型都有对应的悬停处理函数,这些函数负责:

  • 接收悬停事件参数
  • 解析数据信息
  • 生成格式化的工具提示
  • 控制工具提示的显示/隐藏

2. 具体实现流程

2.1 通用流程

  1. 信号触发:鼠标悬停在图表数据点上时,触发hovered信号
  2. 事件处理:对应的处理函数接收信号参数(不同图表类型参数不同)
  3. 数据解析:从参数中提取需要显示的数据(如坐标、数值、标签等)
  4. HTML生成:创建包含样式和数据的HTML工具提示内容
  5. 显示提示:使用QToolTip.showText()显示工具提示

2.2 不同图表类型的实现差异

折线图/曲线图/面积图
defon_line_hovered(self,point,state):ifstateandisinstance(point,QPointF):tooltip_html=f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">数据点</div> <div>X: <span style="color: #3498db;">{point.x():.1f}</span></div> <div>Y: <span style="color: #2ecc71;">{point.y():.1f}</span></div> </div> """QToolTip.showText(QCursor.pos(),tooltip_html,w=None,msecShowTime=3000)else:QToolTip.hideText()
  • 参数point(数据点坐标,QPointF类型)、state(悬停状态,布尔值)
  • 特点:直接显示X/Y坐标值,使用不同颜色区分X/Y值
柱状图
defon_bar_hovered(self,*args):iflen(args)==3:# Pattern: (status, index, barset) - from lambda connectionstatus,index,barset=argsifstatusandbarsetisnotNoneandindex>=0:tooltip_html=f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">{barset.label()}</div> <div>数值: <span style="color: #f39c12;">{barset.at(index)}</span></div> </div> """QToolTip.showText(QCursor.pos(),tooltip_html,w=None,msecShowTime=3000)else:QToolTip.hideText()
  • 参数status(悬停状态)、index(数据索引)、barset(柱状图数据集)
  • 特点:使用lambda函数传递额外的barset参数,显示数据集标签和具体数值
饼图
defon_pie_hovered(self,slice,state):ifstateandsliceisnotNone:tooltip_html=f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">{slice.label()}</div> <div>数值: <span style="color: #9b59b6;">{slice.value():.1f}</span></div> <div>百分比: <span style="color: #1abc9c;">{slice.percentage()*100:.1f}%</span></div> </div> """QToolTip.showText(QCursor.pos(),tooltip_html,w=None,msecShowTime=3000)slice.setExploded(True)# 饼图切片突出显示else:QToolTip.hideText()ifsliceisnotNone:slice.setExploded(False)
  • 参数slice(饼图切片对象)、state(悬停状态)
  • 特点:显示切片标签、数值和百分比,并实现切片突出显示效果

3. 技术特点

3.1 HTML样式的工具提示

  • 使用HTML和内联CSS创建美观的工具提示
  • 支持字体、颜色、布局等样式自定义
  • 不同类型的数据使用不同颜色区分,提高可读性

3.2 自适应不同图表类型

  • 针对不同图表类型的hovered信号参数差异,设计了不同的处理逻辑
  • 柱状图使用lambda函数解决参数传递问题
  • 饼图实现了额外的视觉反馈(切片突出)

3.3 性能优化

  • 仅在悬停状态有效时才生成和显示工具提示
  • 设置工具提示显示时间为3000毫秒,避免长时间占用屏幕
  • 鼠标离开时立即隐藏工具提示

4. 实现优势

  1. 代码复用:相似图表类型的悬停处理函数可以复用(如曲线图和面积图复用折线图的处理函数)
  2. 扩展性强:新增图表类型时,只需添加对应的悬停处理函数即可
  3. 用户体验好:美观的工具提示提供了清晰的数据信息,提升了交互体验
  4. 灵活性高:支持自定义工具提示的样式和内容

通过这种实现方式,Charts Factory 提供了一致且美观的鼠标悬停数据显示功能,增强了图表的交互性和可读性。

```python #!/usr/bin/env python3 """ Charts Factory Module Provides a factory for creating beautiful charts with consistent styling """ import sys import random from PySide6.QtWidgets import QWidget, QVBoxLayout, QToolTip from PySide6.QtCore import Qt, QPointF from PySide6.QtGui import QColor, QPen, QBrush, QFont, QLinearGradient, QPainter, QCursor from PySide6 import QtCharts class ChartsFactory: """ Factory class for creating consistent, beautifully styled charts """ # Default theme colors - Tech style THEME_COLORS = { "background": "#0A0E27", # Dark blue-black background "primary": "#00C8FF", # Bright cyan - main color "secondary": "#6B5B95", # Deep purple "accent1": "#2E8B57", # Dark green "accent2": "#50C878", # Medium green "accent3": "#1E3A8A", # Deep blue "grid": "#1E3A8A", # Dark blue grid lines "text": "#E0E0E0" # Light gray text for readability } # Default color palette for multiple series (e.g., bar charts) - Tech style COLOR_PALETTE = [ "#00C8FF", # Bright cyan - main color "#1E90FF", # Deep blue "#4169E1", # Royal blue "#6A5ACD", # Slate blue "#4B0082", # Indigo "#32CD32", # Lime green (accent) "#20B2AA", # Light sea green "#4682B4", # Steel blue "#708090", # Slate gray "#87CEFA" # Light sky blue ] def __init__(self): """Initialize the charts factory""" pass def create_chart_view(self, chart_type, data, title, **kwargs): """ Create a chart view based on the given type Args: chart_type (str): Type of chart ("line", "spline", "area", "bar", "pie", "scatter", "boxplot") data: Chart data title (str): Chart title **kwargs: Additional parameters Returns: QtCharts.QChartView: Configured chart view """ chart_type_map = { "line": self.create_line_chart, "spline": self.create_spline_chart, "area": self.create_area_chart, "bar": self.create_bar_chart, "horizontal_bar": self.create_horizontal_bar_chart, "pie": self.create_pie_chart, "scatter": self.create_scatter_chart, "boxplot": self.create_boxplot_chart } if chart_type not in chart_type_map: raise ValueError(f"Unsupported chart type: {chart_type}") return chart_type_map[chart_type](data, title, **kwargs) def create_line_chart(self, data, title, **kwargs): """Create a line chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create series series = QtCharts.QLineSeries() series.setName(kwargs.get("series_name", "Data")) # Set series style pen_color = QColor(kwargs.get("color", self.THEME_COLORS["primary"])) pen_width = kwargs.get("line_width", 2) series.setPen(QPen(pen_color, pen_width)) # Add data for x, y in data: series.append(x, y) # Add series to chart chart.addSeries(series) # Connect hovered signal series.hovered.connect(self.on_line_hovered) # Create and configure axes self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_spline_chart(self, data, title, **kwargs): """Create a spline chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create series series = QtCharts.QSplineSeries() series.setName(kwargs.get("series_name", "Data")) # Set series style pen_color = QColor(kwargs.get("color", self.THEME_COLORS["secondary"])) pen_width = kwargs.get("line_width", 2) series.setPen(QPen(pen_color, pen_width)) # Add data for x, y in data: series.append(x, y) # Add series to chart chart.addSeries(series) # Connect hovered signal series.hovered.connect(self.on_spline_hovered) # Create and configure axes self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_area_chart(self, data, title, **kwargs): """Create an area chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create line series for area boundaries line_series = QtCharts.QLineSeries() line_series.setName(kwargs.get("series_name", "Data")) # Add data for x, y in data: line_series.append(x, y) # Create area series with the line series and a base line area_series = QtCharts.QAreaSeries(line_series) # Set area style pen_color = QColor(kwargs.get("color", self.THEME_COLORS["primary"])) area_series.setPen(QPen(pen_color, 2)) # Create gradient fill gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(0, 1) gradient.setColorAt(0, QColor(pen_color.red(), pen_color.green(), pen_color.blue(), 100)) gradient.setColorAt(1, QColor(pen_color.red(), pen_color.green(), pen_color.blue(), 0)) area_series.setBrush(gradient) # Add series to chart chart.addSeries(area_series) # Connect hovered signal area_series.hovered.connect(self.on_area_hovered) # Create and configure axes self._setup_axes(chart, area_series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_bar_chart(self, data, title, **kwargs): """Create a vertical bar chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create bar series series = QtCharts.QBarSeries() # Create bar sets for i, (set_name, values) in enumerate(data.items()): bar_set = QtCharts.QBarSet(set_name) bar_set.append(values) # Set bar set style with different colors if "color" in kwargs: # User specified a single color for all bars pen_color = QColor(kwargs["color"]) else: # Use color from palette based on index pen_color = QColor(self.COLOR_PALETTE[i % len(self.COLOR_PALETTE)]) bar_set.setPen(QPen(pen_color)) bar_set.setBrush(QColor(pen_color)) # Connect hovered signal for this bar set using lambda to pass bar_set reference bar_set.hovered.connect(lambda status, index, bs=bar_set: self.on_bar_hovered(status, index, bs)) series.append(bar_set) # Add series to chart chart.addSeries(series) # Remove incorrect signal connection pass # Create and configure axes self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_horizontal_bar_chart(self, data, title, **kwargs): """Create a horizontal bar chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create bar series series = QtCharts.QHorizontalBarSeries() # Create bar sets for i, (set_name, values) in enumerate(data.items()): bar_set = QtCharts.QBarSet(set_name) bar_set.append(values) # Set bar set style with different colors if "color" in kwargs: # User specified a single color for all bars pen_color = QColor(kwargs["color"]) else: # Use color from palette based on index pen_color = QColor(self.COLOR_PALETTE[i % len(self.COLOR_PALETTE)]) bar_set.setPen(QPen(pen_color)) bar_set.setBrush(QColor(pen_color)) # Connect hovered signal for this bar set using lambda to pass bar_set reference bar_set.hovered.connect(lambda status, index, bs=bar_set: self.on_bar_hovered(status, index, bs)) series.append(bar_set) # Add series to chart chart.addSeries(series) # Create and configure axes (swapped for horizontal bar chart) kwargs["horizontal"] = True self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_pie_chart(self, data, title, **kwargs): """Create a pie chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create pie series series = QtCharts.QPieSeries() # Add data slices using the tech-style color palette for i, (label, value) in enumerate(data.items()): slice = series.append(label, value) slice_color = QColor(self.COLOR_PALETTE[i % len(self.COLOR_PALETTE)]) slice.setBrush(slice_color) slice.setPen(QPen(QColor(self.THEME_COLORS["background"]), 2)) slice.setLabelBrush(QColor(self.THEME_COLORS["text"])) # Make first slice exploded if requested if kwargs.get("explode_first", True) and i == 0: slice.setExploded(True) slice.setLabelVisible(True) # Connect hovered signal for the pie series series.hovered.connect(self.on_pie_hovered) # Add series to chart chart.addSeries(series) # Create chart view return self._create_chart_view(chart) def create_scatter_chart(self, data, title, **kwargs): """Create a scatter chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create scatter series series = QtCharts.QScatterSeries() series.setName(kwargs.get("series_name", "Data")) # Set scatter style pen_color = QColor(kwargs.get("color", self.THEME_COLORS["primary"])) series.setColor(pen_color) series.setMarkerSize(kwargs.get("marker_size", 8)) # Add data for x, y in data: series.append(x, y) # Add series to chart chart.addSeries(series) # Connect hovered signal series.hovered.connect(self.on_scatter_hovered) # Create and configure axes self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def create_boxplot_chart(self, data, title, **kwargs): """Create a box plot chart""" # Create chart chart = QtCharts.QChart() self._setup_chart(chart, title) # Create box plot series series = QtCharts.QBoxPlotSeries() series.setName(kwargs.get("series_name", "Data")) # Set box plot style pen_color = QColor(kwargs.get("color", self.THEME_COLORS["primary"])) series.setPen(QPen(pen_color, 1)) series.setBrush(QColor(pen_color.red(), pen_color.green(), pen_color.blue(), 100)) # Connect hovered signal for the box plot series series.hovered.connect(self.on_boxplot_hovered) # Add data for label, box_data in data.items(): # box_data should be [min, lower_quartile, median, upper_quartile, max] # Correct order: min, lower_quartile, median, upper_quartile, max box = QtCharts.QBoxSet(box_data[0], box_data[1], box_data[2], box_data[3], box_data[4], label) series.append(box) # Add series to chart chart.addSeries(series) # Create and configure axes self._setup_axes(chart, series, **kwargs) # Create chart view return self._create_chart_view(chart) def _setup_chart(self, chart, title): """Setup common chart properties""" # Set chart background chart.setBackgroundBrush(QColor(self.THEME_COLORS["background"])) # Set chart title chart.setTitle(title) chart.setTitleBrush(QColor(self.THEME_COLORS["text"])) # Set animation options chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) return chart def _setup_axes(self, chart, series, **kwargs): """Setup common axis properties""" horizontal_bar = kwargs.get("horizontal", False) # Create X and Y axes based on chart type if isinstance(series, (QtCharts.QBarSeries, QtCharts.QHorizontalBarSeries)): # Bar charts typically use category axes for one dimension if horizontal_bar: axis_x = QtCharts.QValueAxis() axis_y = QtCharts.QCategoryAxis() else: axis_x = QtCharts.QCategoryAxis() axis_y = QtCharts.QValueAxis() else: # Most charts use value axes axis_x = QtCharts.QValueAxis() axis_y = QtCharts.QValueAxis() # Configure X axis axis_x.setTitleText(kwargs.get("x_axis_title", "X Axis")) axis_x.setLabelFormat(kwargs.get("x_label_format", "%.0f")) axis_x.setTickCount(kwargs.get("x_tick_count", 11)) if "x_min" in kwargs and "x_max" in kwargs: axis_x.setRange(kwargs["x_min"], kwargs["x_max"]) # Configure Y axis axis_y.setTitleText(kwargs.get("y_axis_title", "Y Axis")) axis_y.setLabelFormat(kwargs.get("y_label_format", "%.0f")) axis_y.setTickCount(kwargs.get("y_tick_count", 11)) if "y_min" in kwargs and "y_max" in kwargs: axis_y.setRange(kwargs["y_min"], kwargs["y_max"]) # Apply styles to both axes for axis in [axis_x, axis_y]: # Set axis colors axis.setLabelsColor(QColor(self.THEME_COLORS["text"])) axis.setTitleBrush(QColor(self.THEME_COLORS["text"])) # Set grid line style grid_pen = QPen(QColor(self.THEME_COLORS["grid"]), 0.5) axis.setGridLinePen(grid_pen) # Set axis line style axis_pen = QPen(QColor(self.THEME_COLORS["text"]), 1.0) axis.setLinePen(axis_pen) # Add axes to chart if horizontal_bar: chart.addAxis(axis_x, Qt.AlignBottom) chart.addAxis(axis_y, Qt.AlignLeft) else: chart.addAxis(axis_x, Qt.AlignBottom) chart.addAxis(axis_y, Qt.AlignLeft) # Attach series to axes series.attachAxis(axis_x) series.attachAxis(axis_y) return axis_x, axis_y def _create_chart_view(self, chart): """Create a chart view with common settings""" chart_view = QtCharts.QChartView(chart) chart_view.setRenderHint(QPainter.Antialiasing) return chart_view def on_line_hovered(self, point, state): """折线图数据点悬停处理""" if state and isinstance(point, QPointF): tooltip_html = f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">数据点</div> <div>X: <span style="color: #3498db;">{point.x():.1f}</span></div> <div>Y: <span style="color: #2ecc71;">{point.y():.1f}</span></div> </div> """ QToolTip.showText( QCursor.pos(), tooltip_html, w=None, msecShowTime=3000 ) else: QToolTip.hideText() def on_spline_hovered(self, point, state): """曲线图表数据点悬停处理""" self.on_line_hovered(point, state) def on_area_hovered(self, point, state): """面积图表数据点悬停处理""" self.on_line_hovered(point, state) def on_bar_hovered(self, *args): """柱状图悬停处理""" # Handle different parameter patterns if len(args) == 3: # Pattern: (status, index, barset) - from lambda connection status, index, barset = args if status and barset is not None and index >= 0: tooltip_html = f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">{barset.label()}</div> <div>数值: <span style="color: #f39c12;">{barset.at(index)}</span></div> </div> """ QToolTip.showText( QCursor.pos(), tooltip_html, w=None, msecShowTime=3000 ) else: QToolTip.hideText() else: # Fallback if we don't recognize the pattern QToolTip.hideText() def on_pie_hovered(self, slice, state): """饼图悬停处理""" if state and slice is not None: tooltip_html = f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">{slice.label()}</div> <div>数值: <span style="color: #9b59b6;">{slice.value():.1f}</span></div> <div>百分比: <span style="color: #1abc9c;">{slice.percentage()*100:.1f}%</span></div> </div> """ QToolTip.showText( QCursor.pos(), tooltip_html, w=None, msecShowTime=3000 ) slice.setExploded(True) else: QToolTip.hideText() if slice is not None: slice.setExploded(False) def on_scatter_hovered(self, point, state): """散点图悬停处理""" if state and isinstance(point, QPointF): tooltip_html = f""" <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;"> <div style="font-weight: bold; margin-bottom: 4px;">数据点</div> <div>X: <span style="color: #3498db;">{point.x():.1f}</span></div> <div>Y: <span style="color: #e74c3c;">{point.y():.1f}</span></div> </div> """ QToolTip.showText( QCursor.pos(), tooltip_html, w=None, msecShowTime=3000 ) else: QToolTip.hideText() def on_boxplot_hovered(self, state, index, barset): """箱线图悬停处理""" if state and barset is not None and index >= 0: QToolTip.showText( QCursor.pos(), f"组: {barset.label()}", w=None, msecShowTime=3000 ) else: QToolTip.hideText() def create_chart_tab(self, chart_view, tab_name): """Create a tab with the chart view""" tab = QWidget() layout = QVBoxLayout(tab) layout.addWidget(chart_view) return tab # Example usage def main(): """Example demonstrating the charts factory""" from PySide6.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QWidget app = QApplication(sys.argv) # 设置QToolTip样式 app.setStyleSheet(""" QToolTip { background-color: #2c3e50; color: #ecf0f1; border: 1px solid #34495e; border-radius: 4px; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 12px; padding: 8px; opacity: 0.9; } """) # Create main window window = QMainWindow() window.setWindowTitle("Charts Factory Demo") window.setGeometry(100, 100, 1000, 700) # Create central widget and layout central_widget = QWidget() main_layout = QVBoxLayout(central_widget) window.setCentralWidget(central_widget) # Create tab widget tab_widget = QTabWidget() main_layout.addWidget(tab_widget) # Create charts factory factory = ChartsFactory() # Create sample data line_data = [(x, random.randint(0, 100)) for x in range(20)] bar_data = {"Product A": [15, 20, 35, 25, 40], "Product B": [20, 25, 30, 35, 45]} pie_data = {"Company A": 35, "Company B": 25, "Company C": 20, "Company D": 15, "Others": 5} scatter_data = [(random.uniform(0, 100), random.uniform(0, 100)) for _ in range(50)] boxplot_data = { "Set 1": [10, 20, 30, 40, 50], "Set 2": [15, 25, 35, 45, 55], "Set 3": [5, 15, 25, 35, 45] } try: # Create charts one by one with proper error handling print("Creating charts...") # 创建简化的数据以减少资源消耗 simplified_line_data = line_data[:10] # 减少数据点数量 simplified_scatter_data = scatter_data[:20] # 减少散点数量 # 所有支持的图表类型 - 按照资源消耗从低到高排序 all_chart_types = [ ("line", simplified_line_data, "Line Chart"), ("bar", bar_data, "Bar Chart"), ("pie", pie_data, "Pie Chart"), ("scatter", simplified_scatter_data, "Scatter Chart") ] # 扩展图表类型列表,展示所有可用类型(根据系统资源自动调整) extended_chart_types = [ ("spline", simplified_line_data, "Spline Chart"), ("area", simplified_line_data, "Area Chart"), ("horizontal_bar", bar_data, "Horizontal Bar Chart"), ("boxplot", boxplot_data, "Box Plot Chart") ] # 创建图表类型示例 charts_created = 0 max_charts = 4 # 限制同时显示的图表数量以避免资源耗尽 print("=== 基本图表类型示例 ===") for chart_type, data, title in all_chart_types: if charts_created >= max_charts: break print(f"Creating {chart_type} chart...") try: chart_view = factory.create_chart_view(chart_type, data, title) tab = factory.create_chart_tab(chart_view, title) tab_widget.addTab(tab, title) charts_created += 1 print(f"✓ {title} created successfully") except Exception as e: print(f"✗ Error creating {title}: {e}") import traceback traceback.print_exc() # 如果还有资源,创建更多图表类型 print(f"\n=== 扩展图表类型示例 (已创建 {charts_created}/{max_charts} 个) ===") for chart_type, data, title in extended_chart_types: if charts_created >= max_charts: print(f"已达到最大图表数量 ({max_charts}),跳过 {title}") continue print(f"Creating {chart_type} chart...") try: chart_view = factory.create_chart_view(chart_type, data, title) tab = factory.create_chart_tab(chart_view, title) tab_widget.addTab(tab, title) charts_created += 1 print(f"✓ {title} created successfully") except Exception as e: print(f"✗ Error creating {title}: {e}") import traceback traceback.print_exc() print(f"\n共创建了 {charts_created} 个图表类型示例") # 在文档中列出所有可用的图表类型 print("\n=== 所有支持的图表类型 ===") all_supported_types = [ "line (折线图)", "spline (曲线图表)", "area (面积图表)", "bar (条形图)", "horizontal_bar (水平条形图)", "pie (饼图)", "scatter (散点图)", "boxplot (箱线图)" ] for i, chart_type in enumerate(all_supported_types, 1): print(f"{i}. {chart_type}") # Show window window.show() print("Application started successfully!") return app.exec() except Exception as e: print(f"Error: {e}") import traceback traceback.print_exc() return 1 if __name__ == "__main__": main()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 13:59:52

穿搭技巧:让衣品瞬间提升一个档次,时髦又高级

圣罗兰曼哈顿 每个人的审美肯定会有所不同~首先&#xff0c;穿搭最重要的是先让自己满意&#xff0c;要让自己看着都很开心&#xff01;虽然我上学的时候不讲究穿搭&#xff0c;但只要出门玩了我就一定会好好穿搭。 分享一些自己琢磨出来的穿搭小技巧&#xff1a; 1、先确定自己…

作者头像 李华
网站建设 2026/5/13 20:03:16

机箱界的西装暴徒,能打的硬核小钢炮:机械大师C34 Pro装机实测

机箱界的西装暴徒&#xff0c;能打的硬核小钢炮&#xff1a;机械大师C34 Pro装机实测哈喽小伙伴们好&#xff0c;我是Stark-C~话说我分享了那么多的主机电脑机箱&#xff0c;什么海景房、静音侠、模块化、小钢炮……但真正能让我在开箱那一刻就露出“哎哟&#xff0c;这东西有点…

作者头像 李华
网站建设 2026/5/6 17:26:22

深度测评!继续教育必用9个AI论文网站TOP9全解析

深度测评&#xff01;继续教育必用9个AI论文网站TOP9全解析 2026年继续教育AI论文工具测评维度解析 在当前继续教育日益普及的背景下&#xff0c;越来越多的学员需要撰写高质量的学术论文。然而&#xff0c;面对繁重的工作任务与有限的时间&#xff0c;如何高效完成论文写作成为…

作者头像 李华
网站建设 2026/5/16 18:55:49

YOLOv8性能优化实战:CPU推理提速50%的参数详解

YOLOv8性能优化实战&#xff1a;CPU推理提速50%的参数详解 1. 引言&#xff1a;工业级目标检测的性能挑战 在边缘计算和工业视觉场景中&#xff0c;实时性是目标检测系统的核心指标。尽管YOLOv8凭借其高精度与快速推理能力成为主流选择&#xff0c;但在无GPU支持的纯CPU环境下…

作者头像 李华
网站建设 2026/5/16 3:50:45

python自助健身房智能管理系统

目录自助健身房智能管理系统摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;自助健身房智能管理系统摘要 自助健身房智能管理系统通过物联网技术与人工智能算法&#xff0c;实现健身场所…

作者头像 李华
网站建设 2026/5/15 5:15:37

基于大数据的校园网用户行为分析系统的设计与实现_58431u18

目录摘要关键词开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;摘要 校园网作为高校信息化建设的重要组成部分&#xff0c;积累了海量用户行为数据。设计并实现基于大数据的校园网用户行为分…

作者头像 李华