From c2d4262249a95a2dc9a70a97bbbb2ef954c8afd3 Mon Sep 17 00:00:00 2001 From: Irony <892768447@qq.com> Date: Fri, 28 Dec 2018 10:48:24 +0800 Subject: [PATCH] QChart --- .settings/org.eclipse.core.resources.prefs | 10 +- .../PyQtChart/charts/bar => QChart}/BarStack.py | 512 ++++++++-------- .../CustomXYaxis.py | 293 +++++---- {图表/PyQtChart/demo => QChart}/LineChart.py | 72 +-- .../charts/line => QChart}/LineStack.py | 558 +++++++++--------- QChart/README.md | 30 + .../bar => QChart}/ScreenShot/BarStack.gif | Bin .../ScreenShot/CustomXYaxis.png | Bin .../demo => QChart}/ScreenShot/LineChart.png | Bin .../line => QChart}/ScreenShot/LineStack.gif | Bin .../demo => QChart}/ScreenShot/ToolTip.gif | Bin .../demo => QChart}/ScreenShot/ToolTip2.gif | Bin {图表/PyQtChart/demo => QChart}/ToolTip.py | 440 +++++++------- {图表/PyQtChart/demo => QChart}/ToolTip2.py | 438 +++++++------- .../Data}/data.json | 112 ++-- .../Data}/weixin.png | Bin .../ParsingJson.py | 4 +- QTreeWidget/README.md | 8 + .../ScreenShot/ParsingJson.png | Bin .../PyQtChart => Test}/ChartView/ChartView.py | 0 .../PyQtChart => Test}/ChartView/ChatWidget.py | 0 .../PyQtChart => Test}/ChartView/loading.gif | Bin .../ChartView/分类/折线图/堆叠折线图.json | 0 .../ChartView/分类/柱状图/堆叠柱状图.json | 0 图表/README.md | 22 - 树结构/README.md | 8 - 26 files changed, 1252 insertions(+), 1255 deletions(-) rename {图表/PyQtChart/charts/bar => QChart}/BarStack.py (97%) rename 图表/PyQtChart/demo/LineChart自定义xy轴.py => QChart/CustomXYaxis.py (96%) rename {图表/PyQtChart/demo => QChart}/LineChart.py (96%) rename {图表/PyQtChart/charts/line => QChart}/LineStack.py (97%) create mode 100644 QChart/README.md rename {图表/PyQtChart/charts/bar => QChart}/ScreenShot/BarStack.gif (100%) rename 图表/PyQtChart/demo/ScreenShot/LineChart自定义xy轴.png => QChart/ScreenShot/CustomXYaxis.png (100%) rename {图表/PyQtChart/demo => QChart}/ScreenShot/LineChart.png (100%) rename {图表/PyQtChart/charts/line => QChart}/ScreenShot/LineStack.gif (100%) rename {图表/PyQtChart/demo => QChart}/ScreenShot/ToolTip.gif (100%) rename {图表/PyQtChart/demo => QChart}/ScreenShot/ToolTip2.gif (100%) rename {图表/PyQtChart/demo => QChart}/ToolTip.py (93%) rename {图表/PyQtChart/demo => QChart}/ToolTip2.py (95%) rename {树结构/QTreeWidget/Json生成QTreeWidget => QTreeWidget/Data}/data.json (93%) rename {树结构/QTreeWidget/Json生成QTreeWidget => QTreeWidget/Data}/weixin.png (100%) rename 树结构/QTreeWidget/Json生成QTreeWidget/Json生成树形结构.py => QTreeWidget/ParsingJson.py (98%) rename 树结构/QTreeWidget/Json生成QTreeWidget/ScreenShot/Json生成树形结构.png => QTreeWidget/ScreenShot/ParsingJson.png (100%) rename {图表/PyQtChart => Test}/ChartView/ChartView.py (100%) rename {图表/PyQtChart => Test}/ChartView/ChatWidget.py (100%) rename {图表/PyQtChart => Test}/ChartView/loading.gif (100%) rename {图表/PyQtChart => Test}/ChartView/分类/折线图/堆叠折线图.json (100%) rename {图表/PyQtChart => Test}/ChartView/分类/柱状图/堆叠柱状图.json (100%) delete mode 100644 图表/README.md delete mode 100644 树结构/README.md diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index 78beb7e..5f7f528 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -8,6 +8,7 @@ encoding//QTableView/CopyContent/CopyContent.py=utf-8 encoding//QTableView/CopyContent/__main__.py=utf-8 encoding//QTableWidget/SqlQuery/SqlQuery.py=utf-8 encoding//QTableWidget/SqlQuery/__main__.py=utf-8 +encoding//QTreeWidget/ParsingJson.py=utf-8 encoding//\u5176\u5B83/C\u548CC++\u6269\u5C55/py\u8F6Cpyd/pydmod.py=utf-8 encoding//\u5176\u5B83/QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest1.py=utf-8 encoding//\u5176\u5B83/QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest2.py=utf-8 @@ -55,14 +56,6 @@ encoding//\u56FE\u7247/\u663E\u793A.9\u683C\u5F0F\u56FE\u7247/\u7EAFpython\u7248 encoding//\u56FE\u7247/\u663E\u793A.9\u683C\u5F0F\u56FE\u7247/\u7EAFpython\u7248\u672C1/testNinePatch.py=utf-8 encoding//\u56FE\u7247/\u663E\u793A.9\u683C\u5F0F\u56FE\u7247/\u7EAFpython\u7248\u672C2/QtNinePatch.py=utf-8 encoding//\u56FE\u7247/\u663E\u793A.9\u683C\u5F0F\u56FE\u7247/\u7EAFpython\u7248\u672C2/testQtNinePatch.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/ChartView/ChartView.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/ChartView/ChatWidget.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/charts/bar/BarStack.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/charts/line/LineStack.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/demo/LineChart.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/demo/LineChart\u81EA\u5B9A\u4E49xy\u8F74.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/demo/ToolTip.py=utf-8 -encoding//\u56FE\u8868/PyQtChart/demo/ToolTip2.py=utf-8 encoding//\u591A\u7EBF\u7A0B/moveToThread.py=utf-8 encoding//\u591A\u7EBF\u7A0B/\u7EBF\u7A0B\u4F11\u7720\u5524\u9192.py=utf-8 encoding//\u591A\u7EBF\u7A0B/\u7EBF\u7A0B\u6302\u8D77\u6062\u590D.py=utf-8 @@ -70,7 +63,6 @@ encoding//\u591A\u7EBF\u7A0B/\u7EE7\u627FQThread.py=utf-8 encoding//\u591A\u9875\u9762/QScrollArea/\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/SettingUi.py=utf-8 encoding//\u591A\u9875\u9762/QScrollArea/\u4EFFQQ\u8BBE\u7F6E\u9762\u677F/\u4EFFQQ\u8BBE\u7F6E\u9762\u677F.py=utf-8 encoding//\u591A\u9875\u9762/QStackedWidget/\u5DE6\u4FA7\u9009\u9879\u5361/\u5DE6\u4FA7\u9009\u9879\u5361.py=utf-8 -encoding//\u6811\u7ED3\u6784/QTreeWidget/Json\u751F\u6210QTreeWidget/Json\u751F\u6210\u6811\u5F62\u7ED3\u6784.py=utf-8 encoding//\u6D4F\u89C8\u5668/QWebView/\u68A6\u5E7B\u6811/\u68A6\u5E7B\u6811.py=utf-8 encoding//\u6ED1\u52A8\u6761/\u6ED1\u52A8\u6761\u70B9\u51FB\u5B9A\u4F4D.py=utf-8 encoding//\u7A97\u53E3/\u5206\u5272\u7A97\u53E3\u7684\u5206\u5272\u6761\u91CD\u5199.py=utf-8 diff --git a/图表/PyQtChart/charts/bar/BarStack.py b/QChart/BarStack.py similarity index 97% rename from 图表/PyQtChart/charts/bar/BarStack.py rename to QChart/BarStack.py index 87905e9..5e6723f 100644 --- a/图表/PyQtChart/charts/bar/BarStack.py +++ b/QChart/BarStack.py @@ -1,256 +1,256 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月28日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 -@email: 892768447@qq.com -@file: charts.bar.BarStack -@description: like http://echarts.baidu.com/demo.html#bar-stack -''' - -from random import randint -import sys - -from PyQt5.QtChart import QChartView, QChart, QBarSeries, QBarSet, QBarCategoryAxis -from PyQt5.QtCore import Qt, QPointF, QRectF, QPoint -from PyQt5.QtGui import QPainter, QPen -from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QWidget, \ - QHBoxLayout, QLabel, QVBoxLayout, QGraphicsProxyWidget - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -class ToolTipItem(QWidget): - - def __init__(self, color, text, parent=None): - super(ToolTipItem, self).__init__(parent) - layout = QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - clabel = QLabel(self) - clabel.setMinimumSize(12, 12) - clabel.setMaximumSize(12, 12) - clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( - color.red(), color.green(), color.blue(), color.alpha())) - layout.addWidget(clabel) - self.textLabel = QLabel(text, self, styleSheet="color:white;") - layout.addWidget(self.textLabel) - - def setText(self, text): - self.textLabel.setText(text) - - -class ToolTipWidget(QWidget): - - Cache = {} - - def __init__(self, *args, **kwargs): - super(ToolTipWidget, self).__init__(*args, **kwargs) - self.setAttribute(Qt.WA_StyledBackground, True) - self.setStyleSheet( - "ToolTipWidget{background: rgba(50, 50, 50, 100);}") - layout = QVBoxLayout(self) - self.titleLabel = QLabel(self, styleSheet="color:white;") - layout.addWidget(self.titleLabel) - - def updateUi(self, title, bars): - self.titleLabel.setText(title) - for bar, value in bars: - if bar not in self.Cache: - item = ToolTipItem( - bar.color(), - (bar.label() or "-") + ":" + str(value), self) - self.layout().addWidget(item) - self.Cache[bar] = item - else: - self.Cache[bar].setText( - (bar.label() or "-") + ":" + str(value)) - brush = bar.brush() - color = brush.color() - self.Cache[bar].setVisible(color.alphaF() == 1.0) # 隐藏那些不可用的项 - self.adjustSize() # 调整大小 - - -class GraphicsProxyWidget(QGraphicsProxyWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsProxyWidget, self).__init__(*args, **kwargs) - self.setZValue(999) - self.tipWidget = ToolTipWidget() - self.setWidget(self.tipWidget) - self.hide() - - def width(self): - return self.size().width() - - def height(self): - return self.size().height() - - def show(self, title, bars, pos): - self.setGeometry(QRectF(pos, self.size())) - self.tipWidget.updateUi(title, bars) - super(GraphicsProxyWidget, self).show() - - -class ChartView(QChartView): - - def __init__(self, *args, **kwargs): - super(ChartView, self).__init__(*args, **kwargs) - self.resize(800, 600) - self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 - self.initChart() - - # 提示widget - self.toolTipWidget = GraphicsProxyWidget(self._chart) - - # line 宽度需要调整 - self.lineItem = QGraphicsLineItem(self._chart) - pen = QPen(Qt.gray) - self.lineItem.setPen(pen) - self.lineItem.setZValue(998) - self.lineItem.hide() - - # 一些固定计算,减少mouseMoveEvent中的计算量 - # 获取x和y轴的最小最大值 - axisX, axisY = self._chart.axisX(), self._chart.axisY() - self.category_len = len(axisX.categories()) - self.min_x, self.max_x = -0.5, self.category_len - 0.5 - self.min_y, self.max_y = axisY.min(), axisY.max() - # 坐标系中左上角顶点 - self.point_top = self._chart.mapToPosition( - QPointF(self.min_x, self.max_y)) - - def mouseMoveEvent(self, event): - super(ChartView, self).mouseMoveEvent(event) - pos = event.pos() - # 把鼠标位置所在点转换为对应的xy值 - x = self._chart.mapToValue(pos).x() - y = self._chart.mapToValue(pos).y() - index = round(x) - # 得到在坐标系中的所有bar的类型和点 - serie = self._chart.series()[0] - bars = [(bar, bar.at(index)) - for bar in serie.barSets() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] -# print(bars) - if bars: - right_top = self._chart.mapToPosition( - QPointF(self.max_x, self.max_y)) - # 等分距离比例 - step_x = round( - (right_top.x() - self.point_top.x()) / self.category_len) - posx = self._chart.mapToPosition(QPointF(x, self.min_y)) - self.lineItem.setLine(posx.x(), self.point_top.y(), - posx.x(), posx.y()) - self.lineItem.show() - try: - title = self.categories[index] - except: - title = "" - t_width = self.toolTipWidget.width() - t_height = self.toolTipWidget.height() - # 如果鼠标位置离右侧的距离小于tip宽度 - x = pos.x() - t_width if self.width() - \ - pos.x() - 20 < t_width else pos.x() - # 如果鼠标位置离底部的高度小于tip高度 - y = pos.y() - t_height if self.height() - \ - pos.y() - 20 < t_height else pos.y() - self.toolTipWidget.show( - title, bars, QPoint(x, y)) - else: - self.toolTipWidget.hide() - self.lineItem.hide() - - def handleMarkerClicked(self): - marker = self.sender() # 信号发送者 - if not marker: - return - bar = marker.barset() - if not bar: - return - # bar透明度 - brush = bar.brush() - color = brush.color() - alpha = 0.0 if color.alphaF() == 1.0 else 1.0 - color.setAlphaF(alpha) - brush.setColor(color) - bar.setBrush(brush) - # marker - brush = marker.labelBrush() - color = brush.color() - alpha = 0.4 if color.alphaF() == 1.0 else 1.0 - # 设置label的透明度 - color.setAlphaF(alpha) - brush.setColor(color) - marker.setLabelBrush(brush) - # 设置marker的透明度 - brush = marker.brush() - color = brush.color() - color.setAlphaF(alpha) - brush.setColor(color) - marker.setBrush(brush) - - def handleMarkerHovered(self, status): - # 设置bar的画笔宽度 - marker = self.sender() # 信号发送者 - if not marker: - return - bar = marker.barset() - if not bar: - return - pen = bar.pen() - if not pen: - return - pen.setWidth(pen.width() + (1 if status else -1)) - bar.setPen(pen) - - def handleBarHoverd(self, status, index): - # 设置bar的画笔宽度 - bar = self.sender() # 信号发送者 - pen = bar.pen() - if not pen: - return - pen.setWidth(pen.width() + (1 if status else -1)) - bar.setPen(pen) - - def initChart(self): - self._chart = QChart(title="柱状图堆叠") - self._chart.setAcceptHoverEvents(True) - # Series动画 - self._chart.setAnimationOptions(QChart.SeriesAnimations) - self.categories = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] - names = ["邮件营销", "联盟广告", "视频广告", "直接访问", "搜索引擎"] - series = QBarSeries(self._chart) - for name in names: - bar = QBarSet(name) - # 随机数据 - for _ in range(7): - bar.append(randint(0, 10)) - series.append(bar) - bar.hovered.connect(self.handleBarHoverd) # 鼠标悬停 - self._chart.addSeries(series) - self._chart.createDefaultAxes() # 创建默认的轴 - # x轴 - axis_x = QBarCategoryAxis(self._chart) - axis_x.append(self.categories) - self._chart.setAxisX(axis_x, series) - # chart的图例 - legend = self._chart.legend() - legend.setVisible(True) - # 遍历图例上的标记并绑定信号 - for marker in legend.markers(): - # 点击事件 - marker.clicked.connect(self.handleMarkerClicked) - # 鼠标悬停事件 - marker.hovered.connect(self.handleMarkerHovered) - self.setChart(self._chart) - - -if __name__ == "__main__": - app = QApplication(sys.argv) - view = ChartView() - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月28日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 +@email: 892768447@qq.com +@file: charts.bar.BarStack +@description: like http://echarts.baidu.com/demo.html#bar-stack +''' + +from random import randint +import sys + +from PyQt5.QtChart import QChartView, QChart, QBarSeries, QBarSet, QBarCategoryAxis +from PyQt5.QtCore import Qt, QPointF, QRectF, QPoint +from PyQt5.QtGui import QPainter, QPen +from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QWidget, \ + QHBoxLayout, QLabel, QVBoxLayout, QGraphicsProxyWidget + + +__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" +__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" +__Version__ = "Version 1.0" + + +class ToolTipItem(QWidget): + + def __init__(self, color, text, parent=None): + super(ToolTipItem, self).__init__(parent) + layout = QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + clabel = QLabel(self) + clabel.setMinimumSize(12, 12) + clabel.setMaximumSize(12, 12) + clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( + color.red(), color.green(), color.blue(), color.alpha())) + layout.addWidget(clabel) + self.textLabel = QLabel(text, self, styleSheet="color:white;") + layout.addWidget(self.textLabel) + + def setText(self, text): + self.textLabel.setText(text) + + +class ToolTipWidget(QWidget): + + Cache = {} + + def __init__(self, *args, **kwargs): + super(ToolTipWidget, self).__init__(*args, **kwargs) + self.setAttribute(Qt.WA_StyledBackground, True) + self.setStyleSheet( + "ToolTipWidget{background: rgba(50, 50, 50, 100);}") + layout = QVBoxLayout(self) + self.titleLabel = QLabel(self, styleSheet="color:white;") + layout.addWidget(self.titleLabel) + + def updateUi(self, title, bars): + self.titleLabel.setText(title) + for bar, value in bars: + if bar not in self.Cache: + item = ToolTipItem( + bar.color(), + (bar.label() or "-") + ":" + str(value), self) + self.layout().addWidget(item) + self.Cache[bar] = item + else: + self.Cache[bar].setText( + (bar.label() or "-") + ":" + str(value)) + brush = bar.brush() + color = brush.color() + self.Cache[bar].setVisible(color.alphaF() == 1.0) # 隐藏那些不可用的项 + self.adjustSize() # 调整大小 + + +class GraphicsProxyWidget(QGraphicsProxyWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsProxyWidget, self).__init__(*args, **kwargs) + self.setZValue(999) + self.tipWidget = ToolTipWidget() + self.setWidget(self.tipWidget) + self.hide() + + def width(self): + return self.size().width() + + def height(self): + return self.size().height() + + def show(self, title, bars, pos): + self.setGeometry(QRectF(pos, self.size())) + self.tipWidget.updateUi(title, bars) + super(GraphicsProxyWidget, self).show() + + +class ChartView(QChartView): + + def __init__(self, *args, **kwargs): + super(ChartView, self).__init__(*args, **kwargs) + self.resize(800, 600) + self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.initChart() + + # 提示widget + self.toolTipWidget = GraphicsProxyWidget(self._chart) + + # line 宽度需要调整 + self.lineItem = QGraphicsLineItem(self._chart) + pen = QPen(Qt.gray) + self.lineItem.setPen(pen) + self.lineItem.setZValue(998) + self.lineItem.hide() + + # 一些固定计算,减少mouseMoveEvent中的计算量 + # 获取x和y轴的最小最大值 + axisX, axisY = self._chart.axisX(), self._chart.axisY() + self.category_len = len(axisX.categories()) + self.min_x, self.max_x = -0.5, self.category_len - 0.5 + self.min_y, self.max_y = axisY.min(), axisY.max() + # 坐标系中左上角顶点 + self.point_top = self._chart.mapToPosition( + QPointF(self.min_x, self.max_y)) + + def mouseMoveEvent(self, event): + super(ChartView, self).mouseMoveEvent(event) + pos = event.pos() + # 把鼠标位置所在点转换为对应的xy值 + x = self._chart.mapToValue(pos).x() + y = self._chart.mapToValue(pos).y() + index = round(x) + # 得到在坐标系中的所有bar的类型和点 + serie = self._chart.series()[0] + bars = [(bar, bar.at(index)) + for bar in serie.barSets() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] +# print(bars) + if bars: + right_top = self._chart.mapToPosition( + QPointF(self.max_x, self.max_y)) + # 等分距离比例 + step_x = round( + (right_top.x() - self.point_top.x()) / self.category_len) + posx = self._chart.mapToPosition(QPointF(x, self.min_y)) + self.lineItem.setLine(posx.x(), self.point_top.y(), + posx.x(), posx.y()) + self.lineItem.show() + try: + title = self.categories[index] + except: + title = "" + t_width = self.toolTipWidget.width() + t_height = self.toolTipWidget.height() + # 如果鼠标位置离右侧的距离小于tip宽度 + x = pos.x() - t_width if self.width() - \ + pos.x() - 20 < t_width else pos.x() + # 如果鼠标位置离底部的高度小于tip高度 + y = pos.y() - t_height if self.height() - \ + pos.y() - 20 < t_height else pos.y() + self.toolTipWidget.show( + title, bars, QPoint(x, y)) + else: + self.toolTipWidget.hide() + self.lineItem.hide() + + def handleMarkerClicked(self): + marker = self.sender() # 信号发送者 + if not marker: + return + bar = marker.barset() + if not bar: + return + # bar透明度 + brush = bar.brush() + color = brush.color() + alpha = 0.0 if color.alphaF() == 1.0 else 1.0 + color.setAlphaF(alpha) + brush.setColor(color) + bar.setBrush(brush) + # marker + brush = marker.labelBrush() + color = brush.color() + alpha = 0.4 if color.alphaF() == 1.0 else 1.0 + # 设置label的透明度 + color.setAlphaF(alpha) + brush.setColor(color) + marker.setLabelBrush(brush) + # 设置marker的透明度 + brush = marker.brush() + color = brush.color() + color.setAlphaF(alpha) + brush.setColor(color) + marker.setBrush(brush) + + def handleMarkerHovered(self, status): + # 设置bar的画笔宽度 + marker = self.sender() # 信号发送者 + if not marker: + return + bar = marker.barset() + if not bar: + return + pen = bar.pen() + if not pen: + return + pen.setWidth(pen.width() + (1 if status else -1)) + bar.setPen(pen) + + def handleBarHoverd(self, status, index): + # 设置bar的画笔宽度 + bar = self.sender() # 信号发送者 + pen = bar.pen() + if not pen: + return + pen.setWidth(pen.width() + (1 if status else -1)) + bar.setPen(pen) + + def initChart(self): + self._chart = QChart(title="柱状图堆叠") + self._chart.setAcceptHoverEvents(True) + # Series动画 + self._chart.setAnimationOptions(QChart.SeriesAnimations) + self.categories = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] + names = ["邮件营销", "联盟广告", "视频广告", "直接访问", "搜索引擎"] + series = QBarSeries(self._chart) + for name in names: + bar = QBarSet(name) + # 随机数据 + for _ in range(7): + bar.append(randint(0, 10)) + series.append(bar) + bar.hovered.connect(self.handleBarHoverd) # 鼠标悬停 + self._chart.addSeries(series) + self._chart.createDefaultAxes() # 创建默认的轴 + # x轴 + axis_x = QBarCategoryAxis(self._chart) + axis_x.append(self.categories) + self._chart.setAxisX(axis_x, series) + # chart的图例 + legend = self._chart.legend() + legend.setVisible(True) + # 遍历图例上的标记并绑定信号 + for marker in legend.markers(): + # 点击事件 + marker.clicked.connect(self.handleMarkerClicked) + # 鼠标悬停事件 + marker.hovered.connect(self.handleMarkerHovered) + self.setChart(self._chart) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + view = ChartView() + view.show() + sys.exit(app.exec_()) diff --git a/图表/PyQtChart/demo/LineChart自定义xy轴.py b/QChart/CustomXYaxis.py similarity index 96% rename from 图表/PyQtChart/demo/LineChart自定义xy轴.py rename to QChart/CustomXYaxis.py index cf8ecd5..9ab84fb 100644 --- a/图表/PyQtChart/demo/LineChart自定义xy轴.py +++ b/QChart/CustomXYaxis.py @@ -1,147 +1,146 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月19日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, http://coding.net/u/892768447, http://github.com/892768447 -@email: 892768447@qq.com -@file: LineChart自定义xy轴 -@description: -''' -import random -import sys - -from PyQt5.QtChart import QChartView, QLineSeries, QChart, QCategoryAxis -from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout - - -__version__ = "0.0.1" - -m_listCount = 3 -m_valueMax = 10 -m_valueCount = 7 - - -def generateRandomData(listCount, valueMax, valueCount): - random.seed() - dataTable = [] - for i in range(listCount): - dataList = [] - yValue = 0.0 - f_valueCount = float(valueCount) - for j in range(valueCount): - yValue += random.uniform(0, valueMax) / f_valueCount - value = j + random.random() * m_valueMax / f_valueCount, yValue - label = "Slice " + str(i) + ":" + str(j) - dataList.append((value, label)) - dataTable.append(dataList) - return dataTable - - -m_dataTable = generateRandomData(m_listCount, m_valueMax, m_valueCount) - - -def getChart(title): - chart = QChart(title=title) - for i, data_list in enumerate(m_dataTable): - series = QLineSeries(chart) - for value, _ in data_list: - series.append(*value) - series.setName("Series " + str(i)) - chart.addSeries(series) - chart.createDefaultAxes() # 创建默认的轴 - return chart - - -def customAxisX(chart): - # 自定义x轴(均分) - series = chart.series() - if not series: - return - axisx = QCategoryAxis( - chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) - minx = chart.axisX().min() - maxx = chart.axisX().max() - tickc = chart.axisX().tickCount() - if tickc < 2: - axisx.append("lable0", minx) - else: - step = (maxx - minx) / (tickc - 1) # tickc>=2 - for i in range(0, tickc): - axisx.append("lable%s" % i, minx + i * step) - chart.setAxisX(axisx, series[-1]) - - -def customTopAxisX(chart): - # 自定义top x轴 - series = chart.series() - if not series: - return - category = ["%d月" % i for i in range(1, 9)] # 1-8月 - axisx = QCategoryAxis( - chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) - axisx.setGridLineVisible(False) # 隐藏网格线条 - axisx.setTickCount(len(category)) # 设置刻度个数 - chart.axisX().setTickCount(len(category)) # 强制修改x轴的刻度个数一致 - minx = chart.axisX().min() - maxx = chart.axisX().max() - tickc = chart.axisX().tickCount() - step = (maxx - minx) / (tickc - 1) # tickc>=2 - for i in range(0, tickc): - axisx.append(category[i], minx + i * step) - chart.addAxis(axisx, Qt.AlignTop) # 添加到右侧 - series[-1].attachAxis(axisx) # 附加到series上 - - -def customAxisY(chart): - # 自定义y轴(不等分) - series = chart.series() - if not series: - return - category = ["周一", "周二", "周三", "周四", - "周五", "周六", "周日"] - axisy = QCategoryAxis( - chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) - axisy.setGridLineVisible(False) # 隐藏网格线条 - axisy.setTickCount(len(category)) # 设置刻度个数 - miny = chart.axisY().min() - maxy = chart.axisY().max() - tickc = axisy.tickCount() - if tickc < 2: - axisy.append(category[0]) - else: - step = (maxy - miny) / (tickc - 1) # tickc>=2 - for i in range(0, tickc): - axisy.append(category[i], miny + i * step) - chart.addAxis(axisy, Qt.AlignRight) # 添加到右侧 - series[-1].attachAxis(axisy) # 附加到series上 - - -class Window(QWidget): - - def __init__(self, *args, **kwargs): - super(Window, self).__init__(*args, **kwargs) - layout = QHBoxLayout(self) - - # 自定义x轴(和原来的x轴值对应等分) - chart = getChart("自定义x轴(和原来的x轴值对应等分)") - customAxisX(chart) - layout.addWidget(QChartView(chart, self)) - # 自定义添加右侧y轴(等分,与左侧不对应) - chart = getChart("自定义添加右侧y轴(等分,与左侧不对应)") - customAxisY(chart) - layout.addWidget(QChartView(chart, self)) - # 自定义top x轴(按现有新的x轴划分) - chart = getChart("自定义top x轴(按现有新的x轴划分)") - customTopAxisX(chart) - layout.addWidget(QChartView(chart, self)) - - -if __name__ == "__main__": - app = QApplication(sys.argv) - view = Window() - view.resize(800, 600) - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月19日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, http://coding.net/u/892768447, http://github.com/892768447 +@email: 892768447@qq.com +@file: CustomXYaxis +@description: +''' +import random +import sys + +from PyQt5.QtChart import QChartView, QLineSeries, QChart, QCategoryAxis +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout + +__version__ = "0.0.1" + +m_listCount = 3 +m_valueMax = 10 +m_valueCount = 7 + + +def generateRandomData(listCount, valueMax, valueCount): + random.seed() + dataTable = [] + for i in range(listCount): + dataList = [] + yValue = 0.0 + f_valueCount = float(valueCount) + for j in range(valueCount): + yValue += random.uniform(0, valueMax) / f_valueCount + value = j + random.random() * m_valueMax / f_valueCount, yValue + label = "Slice " + str(i) + ":" + str(j) + dataList.append((value, label)) + dataTable.append(dataList) + return dataTable + + +m_dataTable = generateRandomData(m_listCount, m_valueMax, m_valueCount) + + +def getChart(title): + chart = QChart(title=title) + for i, data_list in enumerate(m_dataTable): + series = QLineSeries(chart) + for value, _ in data_list: + series.append(*value) + series.setName("Series " + str(i)) + chart.addSeries(series) + chart.createDefaultAxes() # 创建默认的轴 + return chart + + +def customAxisX(chart): + # 自定义x轴(均分) + series = chart.series() + if not series: + return + axisx = QCategoryAxis( + chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) + minx = chart.axisX().min() + maxx = chart.axisX().max() + tickc = chart.axisX().tickCount() + if tickc < 2: + axisx.append("lable0", minx) + else: + step = (maxx - minx) / (tickc - 1) # tickc>=2 + for i in range(0, tickc): + axisx.append("lable%s" % i, minx + i * step) + chart.setAxisX(axisx, series[-1]) + + +def customTopAxisX(chart): + # 自定义top x轴 + series = chart.series() + if not series: + return + category = ["%d月" % i for i in range(1, 9)] # 1-8月 + axisx = QCategoryAxis( + chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) + axisx.setGridLineVisible(False) # 隐藏网格线条 + axisx.setTickCount(len(category)) # 设置刻度个数 + chart.axisX().setTickCount(len(category)) # 强制修改x轴的刻度个数一致 + minx = chart.axisX().min() + maxx = chart.axisX().max() + tickc = chart.axisX().tickCount() + step = (maxx - minx) / (tickc - 1) # tickc>=2 + for i in range(0, tickc): + axisx.append(category[i], minx + i * step) + chart.addAxis(axisx, Qt.AlignTop) # 添加到右侧 + series[-1].attachAxis(axisx) # 附加到series上 + + +def customAxisY(chart): + # 自定义y轴(不等分) + series = chart.series() + if not series: + return + category = ["周一", "周二", "周三", "周四", + "周五", "周六", "周日"] + axisy = QCategoryAxis( + chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) + axisy.setGridLineVisible(False) # 隐藏网格线条 + axisy.setTickCount(len(category)) # 设置刻度个数 + miny = chart.axisY().min() + maxy = chart.axisY().max() + tickc = axisy.tickCount() + if tickc < 2: + axisy.append(category[0]) + else: + step = (maxy - miny) / (tickc - 1) # tickc>=2 + for i in range(0, tickc): + axisy.append(category[i], miny + i * step) + chart.addAxis(axisy, Qt.AlignRight) # 添加到右侧 + series[-1].attachAxis(axisy) # 附加到series上 + + +class Window(QWidget): + + def __init__(self, *args, **kwargs): + super(Window, self).__init__(*args, **kwargs) + layout = QHBoxLayout(self) + + # 自定义x轴(和原来的x轴值对应等分) + chart = getChart("自定义x轴(和原来的x轴值对应等分)") + customAxisX(chart) + layout.addWidget(QChartView(chart, self)) + # 自定义添加右侧y轴(等分,与左侧不对应) + chart = getChart("自定义添加右侧y轴(等分,与左侧不对应)") + customAxisY(chart) + layout.addWidget(QChartView(chart, self)) + # 自定义top x轴(按现有新的x轴划分) + chart = getChart("自定义top x轴(按现有新的x轴划分)") + customTopAxisX(chart) + layout.addWidget(QChartView(chart, self)) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + view = Window() + view.resize(800, 600) + view.show() + sys.exit(app.exec_()) diff --git a/图表/PyQtChart/demo/LineChart.py b/QChart/LineChart.py similarity index 96% rename from 图表/PyQtChart/demo/LineChart.py rename to QChart/LineChart.py index 526c651..579a00f 100644 --- a/图表/PyQtChart/demo/LineChart.py +++ b/QChart/LineChart.py @@ -1,36 +1,36 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月19日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, http://coding.net/u/892768447, http://github.com/892768447 -@email: 892768447@qq.com -@file: LineChart -@description: -''' -import sys - -from PyQt5.QtChart import QChartView, QLineSeries, QChart -from PyQt5.QtGui import QPainter -from PyQt5.QtWidgets import QApplication - - -__version__ = "0.0.1" - - -if __name__ == "__main__": - app = QApplication(sys.argv) - chart = QChart() - chart.setTitle("Line Chart 1") - series = QLineSeries(chart) - series.append(0, 6) - series.append(2, 4) - chart.addSeries(series) - chart.createDefaultAxes() # 创建默认轴 - - view = QChartView(chart) - view.setRenderHint(QPainter.Antialiasing) # 抗锯齿 - view.resize(800, 600) - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月19日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, http://coding.net/u/892768447, http://github.com/892768447 +@email: 892768447@qq.com +@file: LineChart +@description: +''' +import sys + +from PyQt5.QtChart import QChartView, QLineSeries, QChart +from PyQt5.QtGui import QPainter +from PyQt5.QtWidgets import QApplication + + +__version__ = "0.0.1" + + +if __name__ == "__main__": + app = QApplication(sys.argv) + chart = QChart() + chart.setTitle("Line Chart 1") + series = QLineSeries(chart) + series.append(0, 6) + series.append(2, 4) + chart.addSeries(series) + chart.createDefaultAxes() # 创建默认轴 + + view = QChartView(chart) + view.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + view.resize(800, 600) + view.show() + sys.exit(app.exec_()) diff --git a/图表/PyQtChart/charts/line/LineStack.py b/QChart/LineStack.py similarity index 97% rename from 图表/PyQtChart/charts/line/LineStack.py rename to QChart/LineStack.py index e04262e..065095f 100644 --- a/图表/PyQtChart/charts/line/LineStack.py +++ b/QChart/LineStack.py @@ -1,279 +1,279 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月28日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 -@email: 892768447@qq.com -@file: charts.line.LineStack -@description: like http://echarts.baidu.com/demo.html#line-stack -''' - -import sys - -from PyQt5.QtChart import QChartView, QChart, QLineSeries, QLegend,\ - QCategoryAxis -from PyQt5.QtCore import Qt, QPointF, QRectF, QPoint -from PyQt5.QtGui import QPainter, QPen -from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QWidget, \ - QHBoxLayout, QLabel, QVBoxLayout, QGraphicsProxyWidget - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -class ToolTipItem(QWidget): - - def __init__(self, color, text, parent=None): - super(ToolTipItem, self).__init__(parent) - layout = QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - clabel = QLabel(self) - clabel.setMinimumSize(12, 12) - clabel.setMaximumSize(12, 12) - clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( - color.red(), color.green(), color.blue(), color.alpha())) - layout.addWidget(clabel) - self.textLabel = QLabel(text, self, styleSheet="color:white;") - layout.addWidget(self.textLabel) - - def setText(self, text): - self.textLabel.setText(text) - - -class ToolTipWidget(QWidget): - - Cache = {} - - def __init__(self, *args, **kwargs): - super(ToolTipWidget, self).__init__(*args, **kwargs) - self.setAttribute(Qt.WA_StyledBackground, True) - self.setStyleSheet( - "ToolTipWidget{background: rgba(50, 50, 50, 100);}") - layout = QVBoxLayout(self) - self.titleLabel = QLabel(self, styleSheet="color:white;") - layout.addWidget(self.titleLabel) - - def updateUi(self, title, points): - self.titleLabel.setText(title) - for serie, point in points: - if serie not in self.Cache: - item = ToolTipItem( - serie.color(), - (serie.name() or "-") + ":" + str(point.y()), self) - self.layout().addWidget(item) - self.Cache[serie] = item - else: - self.Cache[serie].setText( - (serie.name() or "-") + ":" + str(point.y())) - self.Cache[serie].setVisible(serie.isVisible()) # 隐藏那些不可用的项 - self.adjustSize() # 调整大小 - - -class GraphicsProxyWidget(QGraphicsProxyWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsProxyWidget, self).__init__(*args, **kwargs) - self.setZValue(999) - self.tipWidget = ToolTipWidget() - self.setWidget(self.tipWidget) - self.hide() - - def width(self): - return self.size().width() - - def height(self): - return self.size().height() - - def show(self, title, points, pos): - self.setGeometry(QRectF(pos, self.size())) - self.tipWidget.updateUi(title, points) - super(GraphicsProxyWidget, self).show() - - -class ChartView(QChartView): - - def __init__(self, *args, **kwargs): - super(ChartView, self).__init__(*args, **kwargs) - self.resize(800, 600) - self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 - # 自定义x轴label - self.category = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] - self.initChart() - - # 提示widget - self.toolTipWidget = GraphicsProxyWidget(self._chart) - - # line - self.lineItem = QGraphicsLineItem(self._chart) - pen = QPen(Qt.gray) - pen.setWidth(1) - self.lineItem.setPen(pen) - self.lineItem.setZValue(998) - self.lineItem.hide() - - # 一些固定计算,减少mouseMoveEvent中的计算量 - # 获取x和y轴的最小最大值 - axisX, axisY = self._chart.axisX(), self._chart.axisY() - self.min_x, self.max_x = axisX.min(), axisX.max() - self.min_y, self.max_y = axisY.min(), axisY.max() - - def resizeEvent(self, event): - super(ChartView, self).resizeEvent(event) - # 当窗口大小改变时需要重新计算 - # 坐标系中左上角顶点 - self.point_top = self._chart.mapToPosition( - QPointF(self.min_x, self.max_y)) - # 坐标原点坐标 - self.point_bottom = self._chart.mapToPosition( - QPointF(self.min_x, self.min_y)) - self.step_x = (self.max_x - self.min_x) / \ - (self._chart.axisX().tickCount() - 1) - - def mouseMoveEvent(self, event): - super(ChartView, self).mouseMoveEvent(event) - pos = event.pos() - # 把鼠标位置所在点转换为对应的xy值 - x = self._chart.mapToValue(pos).x() - y = self._chart.mapToValue(pos).y() - index = round((x - self.min_x) / self.step_x) - # 得到在坐标系中的所有正常显示的series的类型和点 - points = [(serie, serie.at(index)) - for serie in self._chart.series() - if self.min_x <= x <= self.max_x and - self.min_y <= y <= self.max_y] - if points: - pos_x = self._chart.mapToPosition( - QPointF(index * self.step_x + self.min_x, self.min_y)) - self.lineItem.setLine(pos_x.x(), self.point_top.y(), - pos_x.x(), self.point_bottom.y()) - self.lineItem.show() - try: - title = self.category[index] - except: - title = "" - t_width = self.toolTipWidget.width() - t_height = self.toolTipWidget.height() - # 如果鼠标位置离右侧的距离小于tip宽度 - x = pos.x() - t_width if self.width() - \ - pos.x() - 20 < t_width else pos.x() - # 如果鼠标位置离底部的高度小于tip高度 - y = pos.y() - t_height if self.height() - \ - pos.y() - 20 < t_height else pos.y() - self.toolTipWidget.show( - title, points, QPoint(x, y)) - else: - self.toolTipWidget.hide() - self.lineItem.hide() - - def handleMarkerClicked(self): - marker = self.sender() # 信号发送者 - if not marker: - return - visible = not marker.series().isVisible() -# # 隐藏或显示series - marker.series().setVisible(visible) - marker.setVisible(True) # 要保证marker一直显示 - # 透明度 - alpha = 1.0 if visible else 0.4 - # 设置label的透明度 - brush = marker.labelBrush() - color = brush.color() - color.setAlphaF(alpha) - brush.setColor(color) - marker.setLabelBrush(brush) - # 设置marker的透明度 - brush = marker.brush() - color = brush.color() - color.setAlphaF(alpha) - brush.setColor(color) - marker.setBrush(brush) - # 设置画笔透明度 - pen = marker.pen() - color = pen.color() - color.setAlphaF(alpha) - pen.setColor(color) - marker.setPen(pen) - - def handleMarkerHovered(self, status): - # 设置series的画笔宽度 - marker = self.sender() # 信号发送者 - if not marker: - return - series = marker.series() - if not series: - return - pen = series.pen() - if not pen: - return - pen.setWidth(pen.width() + (1 if status else -1)) - series.setPen(pen) - - def handleSeriesHoverd(self, point, state): - # 设置series的画笔宽度 - series = self.sender() # 信号发送者 - pen = series.pen() - if not pen: - return - pen.setWidth(pen.width() + (1 if state else -1)) - series.setPen(pen) - - def initChart(self): - self._chart = QChart(title="折线图堆叠") - self._chart.setAcceptHoverEvents(True) - # Series动画 - self._chart.setAnimationOptions(QChart.SeriesAnimations) - dataTable = [ - ["邮件营销", [120, 132, 101, 134, 90, 230, 210]], - ["联盟广告", [220, 182, 191, 234, 290, 330, 310]], - ["视频广告", [150, 232, 201, 154, 190, 330, 410]], - ["直接访问", [320, 332, 301, 334, 390, 330, 320]], - ["搜索引擎", [820, 932, 901, 934, 1290, 1330, 1320]] - ] - for series_name, data_list in dataTable: - series = QLineSeries(self._chart) - for j, v in enumerate(data_list): - series.append(j, v) - series.setName(series_name) - series.setPointsVisible(True) # 显示圆点 - series.hovered.connect(self.handleSeriesHoverd) # 鼠标悬停 - self._chart.addSeries(series) - self._chart.createDefaultAxes() # 创建默认的轴 - axisX = self._chart.axisX() # x轴 - axisX.setTickCount(7) # x轴设置7个刻度 - axisX.setGridLineVisible(False) # 隐藏从x轴往上的线条 - axisY = self._chart.axisY() - axisY.setTickCount(7) # y轴设置7个刻度 - axisY.setRange(0, 1500) # 设置y轴范围 - # 自定义x轴 - axis_x = QCategoryAxis( - self._chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) - axis_x.setTickCount(7) - axis_x.setGridLineVisible(False) - min_x = axisX.min() - max_x = axisX.max() - step = (max_x - min_x) / (7 - 1) # 7个tick - for i in range(0, 7): - axis_x.append(self.category[i], min_x + i * step) - self._chart.setAxisX(axis_x, self._chart.series()[-1]) - # chart的图例 - legend = self._chart.legend() - # 设置图例由Series来决定样式 - legend.setMarkerShape(QLegend.MarkerShapeFromSeries) - # 遍历图例上的标记并绑定信号 - for marker in legend.markers(): - # 点击事件 - marker.clicked.connect(self.handleMarkerClicked) - # 鼠标悬停事件 - marker.hovered.connect(self.handleMarkerHovered) - self.setChart(self._chart) - - -if __name__ == "__main__": - app = QApplication(sys.argv) - view = ChartView() - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月28日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 +@email: 892768447@qq.com +@file: charts.line.LineStack +@description: like http://echarts.baidu.com/demo.html#line-stack +''' + +import sys + +from PyQt5.QtChart import QChartView, QChart, QLineSeries, QLegend,\ + QCategoryAxis +from PyQt5.QtCore import Qt, QPointF, QRectF, QPoint +from PyQt5.QtGui import QPainter, QPen +from PyQt5.QtWidgets import QApplication, QGraphicsLineItem, QWidget, \ + QHBoxLayout, QLabel, QVBoxLayout, QGraphicsProxyWidget + + +__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" +__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" +__Version__ = "Version 1.0" + + +class ToolTipItem(QWidget): + + def __init__(self, color, text, parent=None): + super(ToolTipItem, self).__init__(parent) + layout = QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + clabel = QLabel(self) + clabel.setMinimumSize(12, 12) + clabel.setMaximumSize(12, 12) + clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( + color.red(), color.green(), color.blue(), color.alpha())) + layout.addWidget(clabel) + self.textLabel = QLabel(text, self, styleSheet="color:white;") + layout.addWidget(self.textLabel) + + def setText(self, text): + self.textLabel.setText(text) + + +class ToolTipWidget(QWidget): + + Cache = {} + + def __init__(self, *args, **kwargs): + super(ToolTipWidget, self).__init__(*args, **kwargs) + self.setAttribute(Qt.WA_StyledBackground, True) + self.setStyleSheet( + "ToolTipWidget{background: rgba(50, 50, 50, 100);}") + layout = QVBoxLayout(self) + self.titleLabel = QLabel(self, styleSheet="color:white;") + layout.addWidget(self.titleLabel) + + def updateUi(self, title, points): + self.titleLabel.setText(title) + for serie, point in points: + if serie not in self.Cache: + item = ToolTipItem( + serie.color(), + (serie.name() or "-") + ":" + str(point.y()), self) + self.layout().addWidget(item) + self.Cache[serie] = item + else: + self.Cache[serie].setText( + (serie.name() or "-") + ":" + str(point.y())) + self.Cache[serie].setVisible(serie.isVisible()) # 隐藏那些不可用的项 + self.adjustSize() # 调整大小 + + +class GraphicsProxyWidget(QGraphicsProxyWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsProxyWidget, self).__init__(*args, **kwargs) + self.setZValue(999) + self.tipWidget = ToolTipWidget() + self.setWidget(self.tipWidget) + self.hide() + + def width(self): + return self.size().width() + + def height(self): + return self.size().height() + + def show(self, title, points, pos): + self.setGeometry(QRectF(pos, self.size())) + self.tipWidget.updateUi(title, points) + super(GraphicsProxyWidget, self).show() + + +class ChartView(QChartView): + + def __init__(self, *args, **kwargs): + super(ChartView, self).__init__(*args, **kwargs) + self.resize(800, 600) + self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + # 自定义x轴label + self.category = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"] + self.initChart() + + # 提示widget + self.toolTipWidget = GraphicsProxyWidget(self._chart) + + # line + self.lineItem = QGraphicsLineItem(self._chart) + pen = QPen(Qt.gray) + pen.setWidth(1) + self.lineItem.setPen(pen) + self.lineItem.setZValue(998) + self.lineItem.hide() + + # 一些固定计算,减少mouseMoveEvent中的计算量 + # 获取x和y轴的最小最大值 + axisX, axisY = self._chart.axisX(), self._chart.axisY() + self.min_x, self.max_x = axisX.min(), axisX.max() + self.min_y, self.max_y = axisY.min(), axisY.max() + + def resizeEvent(self, event): + super(ChartView, self).resizeEvent(event) + # 当窗口大小改变时需要重新计算 + # 坐标系中左上角顶点 + self.point_top = self._chart.mapToPosition( + QPointF(self.min_x, self.max_y)) + # 坐标原点坐标 + self.point_bottom = self._chart.mapToPosition( + QPointF(self.min_x, self.min_y)) + self.step_x = (self.max_x - self.min_x) / \ + (self._chart.axisX().tickCount() - 1) + + def mouseMoveEvent(self, event): + super(ChartView, self).mouseMoveEvent(event) + pos = event.pos() + # 把鼠标位置所在点转换为对应的xy值 + x = self._chart.mapToValue(pos).x() + y = self._chart.mapToValue(pos).y() + index = round((x - self.min_x) / self.step_x) + # 得到在坐标系中的所有正常显示的series的类型和点 + points = [(serie, serie.at(index)) + for serie in self._chart.series() + if self.min_x <= x <= self.max_x and + self.min_y <= y <= self.max_y] + if points: + pos_x = self._chart.mapToPosition( + QPointF(index * self.step_x + self.min_x, self.min_y)) + self.lineItem.setLine(pos_x.x(), self.point_top.y(), + pos_x.x(), self.point_bottom.y()) + self.lineItem.show() + try: + title = self.category[index] + except: + title = "" + t_width = self.toolTipWidget.width() + t_height = self.toolTipWidget.height() + # 如果鼠标位置离右侧的距离小于tip宽度 + x = pos.x() - t_width if self.width() - \ + pos.x() - 20 < t_width else pos.x() + # 如果鼠标位置离底部的高度小于tip高度 + y = pos.y() - t_height if self.height() - \ + pos.y() - 20 < t_height else pos.y() + self.toolTipWidget.show( + title, points, QPoint(x, y)) + else: + self.toolTipWidget.hide() + self.lineItem.hide() + + def handleMarkerClicked(self): + marker = self.sender() # 信号发送者 + if not marker: + return + visible = not marker.series().isVisible() +# # 隐藏或显示series + marker.series().setVisible(visible) + marker.setVisible(True) # 要保证marker一直显示 + # 透明度 + alpha = 1.0 if visible else 0.4 + # 设置label的透明度 + brush = marker.labelBrush() + color = brush.color() + color.setAlphaF(alpha) + brush.setColor(color) + marker.setLabelBrush(brush) + # 设置marker的透明度 + brush = marker.brush() + color = brush.color() + color.setAlphaF(alpha) + brush.setColor(color) + marker.setBrush(brush) + # 设置画笔透明度 + pen = marker.pen() + color = pen.color() + color.setAlphaF(alpha) + pen.setColor(color) + marker.setPen(pen) + + def handleMarkerHovered(self, status): + # 设置series的画笔宽度 + marker = self.sender() # 信号发送者 + if not marker: + return + series = marker.series() + if not series: + return + pen = series.pen() + if not pen: + return + pen.setWidth(pen.width() + (1 if status else -1)) + series.setPen(pen) + + def handleSeriesHoverd(self, point, state): + # 设置series的画笔宽度 + series = self.sender() # 信号发送者 + pen = series.pen() + if not pen: + return + pen.setWidth(pen.width() + (1 if state else -1)) + series.setPen(pen) + + def initChart(self): + self._chart = QChart(title="折线图堆叠") + self._chart.setAcceptHoverEvents(True) + # Series动画 + self._chart.setAnimationOptions(QChart.SeriesAnimations) + dataTable = [ + ["邮件营销", [120, 132, 101, 134, 90, 230, 210]], + ["联盟广告", [220, 182, 191, 234, 290, 330, 310]], + ["视频广告", [150, 232, 201, 154, 190, 330, 410]], + ["直接访问", [320, 332, 301, 334, 390, 330, 320]], + ["搜索引擎", [820, 932, 901, 934, 1290, 1330, 1320]] + ] + for series_name, data_list in dataTable: + series = QLineSeries(self._chart) + for j, v in enumerate(data_list): + series.append(j, v) + series.setName(series_name) + series.setPointsVisible(True) # 显示圆点 + series.hovered.connect(self.handleSeriesHoverd) # 鼠标悬停 + self._chart.addSeries(series) + self._chart.createDefaultAxes() # 创建默认的轴 + axisX = self._chart.axisX() # x轴 + axisX.setTickCount(7) # x轴设置7个刻度 + axisX.setGridLineVisible(False) # 隐藏从x轴往上的线条 + axisY = self._chart.axisY() + axisY.setTickCount(7) # y轴设置7个刻度 + axisY.setRange(0, 1500) # 设置y轴范围 + # 自定义x轴 + axis_x = QCategoryAxis( + self._chart, labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue) + axis_x.setTickCount(7) + axis_x.setGridLineVisible(False) + min_x = axisX.min() + max_x = axisX.max() + step = (max_x - min_x) / (7 - 1) # 7个tick + for i in range(0, 7): + axis_x.append(self.category[i], min_x + i * step) + self._chart.setAxisX(axis_x, self._chart.series()[-1]) + # chart的图例 + legend = self._chart.legend() + # 设置图例由Series来决定样式 + legend.setMarkerShape(QLegend.MarkerShapeFromSeries) + # 遍历图例上的标记并绑定信号 + for marker in legend.markers(): + # 点击事件 + marker.clicked.connect(self.handleMarkerClicked) + # 鼠标悬停事件 + marker.hovered.connect(self.handleMarkerHovered) + self.setChart(self._chart) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + view = ChartView() + view.show() + sys.exit(app.exec_()) diff --git a/QChart/README.md b/QChart/README.md new file mode 100644 index 0000000..fb1ca58 --- /dev/null +++ b/QChart/README.md @@ -0,0 +1,30 @@ +# QChart + +## 1、折线图 +[运行 LineChart.py](LineChart.py) + +![LineChart](ScreenShot/LineChart.png) + +## 2、折线堆叠图 +[运行 LineStack.py](LineStack.py) + +仿照 [line-stack](http://echarts.baidu.com/demo.html#line-stack) + +![LineStack](ScreenShot/LineStack.gif) + +## 3、柱状堆叠图 +[运行 BarStack.py](BarStack.py) + +仿照 [bar-stack](http://echarts.baidu.com/demo.html#bar-stack) + +![BarStack](ScreenShot/BarStack.gif) + +## 4、LineChart自定义xy轴 +[运行 CustomXYaxis.py](CustomXYaxis.py) + +![CustomXYaxis](ScreenShot/CustomXYaxis.png) + +## 5、ToolTip提示 +[运行 ToolTip.py](ToolTip.py) | [运行 ToolTip2.py](ToolTip2.py) + +![ToolTip](ScreenShot/ToolTip.gif) ![ToolTip2](ScreenShot/ToolTip2.gif) \ No newline at end of file diff --git a/图表/PyQtChart/charts/bar/ScreenShot/BarStack.gif b/QChart/ScreenShot/BarStack.gif similarity index 100% rename from 图表/PyQtChart/charts/bar/ScreenShot/BarStack.gif rename to QChart/ScreenShot/BarStack.gif diff --git a/图表/PyQtChart/demo/ScreenShot/LineChart自定义xy轴.png b/QChart/ScreenShot/CustomXYaxis.png similarity index 100% rename from 图表/PyQtChart/demo/ScreenShot/LineChart自定义xy轴.png rename to QChart/ScreenShot/CustomXYaxis.png diff --git a/图表/PyQtChart/demo/ScreenShot/LineChart.png b/QChart/ScreenShot/LineChart.png similarity index 100% rename from 图表/PyQtChart/demo/ScreenShot/LineChart.png rename to QChart/ScreenShot/LineChart.png diff --git a/图表/PyQtChart/charts/line/ScreenShot/LineStack.gif b/QChart/ScreenShot/LineStack.gif similarity index 100% rename from 图表/PyQtChart/charts/line/ScreenShot/LineStack.gif rename to QChart/ScreenShot/LineStack.gif diff --git a/图表/PyQtChart/demo/ScreenShot/ToolTip.gif b/QChart/ScreenShot/ToolTip.gif similarity index 100% rename from 图表/PyQtChart/demo/ScreenShot/ToolTip.gif rename to QChart/ScreenShot/ToolTip.gif diff --git a/图表/PyQtChart/demo/ScreenShot/ToolTip2.gif b/QChart/ScreenShot/ToolTip2.gif similarity index 100% rename from 图表/PyQtChart/demo/ScreenShot/ToolTip2.gif rename to QChart/ScreenShot/ToolTip2.gif diff --git a/图表/PyQtChart/demo/ToolTip.py b/QChart/ToolTip.py similarity index 93% rename from 图表/PyQtChart/demo/ToolTip.py rename to QChart/ToolTip.py index 1b2afaf..42af2bf 100644 --- a/图表/PyQtChart/demo/ToolTip.py +++ b/QChart/ToolTip.py @@ -1,220 +1,220 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月23日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 -@email: 892768447@qq.com -@file: ToolTip -@description: -''' -import sys - -from PyQt5.QtChart import QChartView, QChart, QLineSeries -from PyQt5.QtCore import Qt, QRectF, QPoint, QPointF -from PyQt5.QtGui import QPainter, QCursor -from PyQt5.QtWidgets import QApplication, QGraphicsProxyWidget, QLabel, \ - QWidget, QHBoxLayout, QVBoxLayout, QToolTip, QGraphicsLineItem - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -''' -class CircleWidget(QGraphicsProxyWidget): - - def __init__(self, color, *args, **kwargs): - super(CircleWidget, self).__init__(*args, **kwargs) - label = QLabel() - label.setMinimumSize(12, 12) - label.setMaximumSize(12, 12) - label.setStyleSheet( - "border:1px solid green;border-radius:6px;background: %s;" % color) - self.setWidget(label) - - -class TextWidget(QGraphicsProxyWidget): - - def __init__(self, text, *args, **kwargs): - super(TextWidget, self).__init__(*args, **kwargs) - self.setWidget(QLabel(text, styleSheet="color:white;")) - - -class GraphicsWidget(QGraphicsWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsWidget, self).__init__(*args, **kwargs) -# self.setFlags(self.ItemClipsChildrenToShape) - self.setZValue(999) - layout = QGraphicsGridLayout(self) - for row in range(6): - layout.addItem(CircleWidget("red"), row, 0) - layout.addItem(TextWidget("red"), row, 1) - self.hide() - - def show(self, pos): - self.setGeometry(pos.x(), pos.y(), self.size().width(), - self.size().height()) - super(GraphicsWidget, self).show() -''' - - -class ToolTipItem(QWidget): - - def __init__(self, color, text, parent=None): - super(ToolTipItem, self).__init__(parent) - layout = QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - clabel = QLabel(self) - clabel.setMinimumSize(12, 12) - clabel.setMaximumSize(12, 12) - clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( - color.red(), color.green(), color.blue(), color.alpha())) - layout.addWidget(clabel) - self.textLabel = QLabel(text, self, styleSheet="color:white;") - layout.addWidget(self.textLabel) - - def setText(self, text): - self.textLabel.setText(text) - - -class ToolTipWidget(QWidget): - - Cache = {} - - def __init__(self, *args, **kwargs): - super(ToolTipWidget, self).__init__(*args, **kwargs) - self.setAttribute(Qt.WA_StyledBackground, True) - self.setStyleSheet( - "ToolTipWidget{background: rgba(50,50,50,70);}") - layout = QVBoxLayout(self) - self.titleLabel = QLabel(self, styleSheet="color:white;") - layout.addWidget(self.titleLabel) - - def updateUi(self, title, points): - self.titleLabel.setText(title) - for serie, point in points: - if serie not in self.Cache: - item = ToolTipItem( - serie.color(), - (serie.name() or "-") + ":" + str(point.y()), self) - self.layout().addWidget(item) - self.Cache[serie] = item - else: - self.Cache[serie].setText( - (serie.name() or "-") + ":" + str(point.y())) - - -class GraphicsProxyWidget(QGraphicsProxyWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsProxyWidget, self).__init__(*args, **kwargs) - self.setZValue(999) - self.tipWidget = ToolTipWidget() - self.setWidget(self.tipWidget) - self.hide() - - def show(self, title, points, pos): - self.setGeometry(QRectF(pos, self.size())) - self.tipWidget.updateUi(title, points) - super(GraphicsProxyWidget, self).show() - - -class ChartView(QChartView): - - def __init__(self, *args, **kwargs): - super(ChartView, self).__init__(*args, **kwargs) - self.resize(800, 600) - self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 - self.initChart() - - self.toolTipWidget = GraphicsProxyWidget(self._chart) - - # line - self.lineItem = QGraphicsLineItem(self._chart) - self.lineItem.setZValue(998) - self.lineItem.hide() - - # 一些固定计算,减少mouseMoveEvent中的计算量 - # 获取x和y轴的最小最大值 - axisX, axisY = self._chart.axisX(), self._chart.axisY() - self.min_x, self.max_x = axisX.min(), axisX.max() - self.min_y, self.max_y = axisY.min(), axisY.max() - # 坐标系中左上角顶点 - self.point_top = self._chart.mapToPosition(QPointF(self.min_x, self.max_y)) - # 坐标原点坐标 - self.point_bottom = self._chart.mapToPosition(QPointF(self.min_x, self.min_y)) - self.step_x = (self.max_x - self.min_x) / (axisX.tickCount() - 1) -# self.step_y = (self.max_y - self.min_y) / (axisY.tickCount() - 1) - - def mouseMoveEvent(self, event): - super(ChartView, self).mouseMoveEvent(event) - # 把鼠标位置所在点转换为对应的xy值 - x = self._chart.mapToValue(event.pos()).x() - y = self._chart.mapToValue(event.pos()).y() - index = round((x - self.min_x) / self.step_x) - pos_x = self._chart.mapToPosition( - QPointF(index * self.step_x + self.min_x, self.min_y)) -# print(x, pos_x, index, index * self.step_x + self.min_x) - # 得到在坐标系中的所有series的类型和点 - points = [(serie, serie.at(index)) - for serie in self._chart.series() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] - if points: - # 永远在轴上的黑线条 - self.lineItem.setLine(pos_x.x(), self.point_top.y(), - pos_x.x(), self.point_bottom.y()) - self.lineItem.show() - self.toolTipWidget.show("", points, event.pos() + QPoint(20, 20)) - else: - self.toolTipWidget.hide() - self.lineItem.hide() - - def onSeriesHoverd(self, point, state): - if state: - try: - name = self.sender().name() - except: - name = "" - QToolTip.showText(QCursor.pos(), "%s\nx: %s\ny: %s" % - (name, point.x(), point.y())) - - def initChart(self): - self._chart = QChart(title="Line Chart") - self._chart.setAcceptHoverEvents(True) - dataTable = [ - [120, 132, 101, 134, 90, 230, 210], - [220, 182, 191, 234, 290, 330, 310], - [150, 232, 201, 154, 190, 330, 410], - [320, 332, 301, 334, 390, 330, 320], - [820, 932, 901, 934, 1290, 1330, 1320] - ] - for i, data_list in enumerate(dataTable): - series = QLineSeries(self._chart) - for j, v in enumerate(data_list): - series.append(j, v) - series.setName("Series " + str(i)) - series.setPointsVisible(True) # 显示原点 - series.hovered.connect(self.onSeriesHoverd) - self._chart.addSeries(series) - self._chart.createDefaultAxes() # 创建默认的轴 - self._chart.axisX().setTickCount(7) # x轴设置7个刻度 - self._chart.axisY().setTickCount(7) # y轴设置7个刻度 - self._chart.axisY().setRange(0, 1500) # 设置y轴范围 - self.setChart(self._chart) - - -if __name__ == "__main__": - app = QApplication(sys.argv) - app.setStyleSheet("""QToolTip { - border: none; - padding: 5px; - color: white; - background: rgb(50,50,50); - opacity: 100; -}""") - view = ChartView() - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月23日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 +@email: 892768447@qq.com +@file: ToolTip +@description: +''' +import sys + +from PyQt5.QtChart import QChartView, QChart, QLineSeries +from PyQt5.QtCore import Qt, QRectF, QPoint, QPointF +from PyQt5.QtGui import QPainter, QCursor +from PyQt5.QtWidgets import QApplication, QGraphicsProxyWidget, QLabel, \ + QWidget, QHBoxLayout, QVBoxLayout, QToolTip, QGraphicsLineItem + +__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" +__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" +__Version__ = "Version 1.0" + +''' +class CircleWidget(QGraphicsProxyWidget): + + def __init__(self, color, *args, **kwargs): + super(CircleWidget, self).__init__(*args, **kwargs) + label = QLabel() + label.setMinimumSize(12, 12) + label.setMaximumSize(12, 12) + label.setStyleSheet( + "border:1px solid green;border-radius:6px;background: %s;" % color) + self.setWidget(label) + + +class TextWidget(QGraphicsProxyWidget): + + def __init__(self, text, *args, **kwargs): + super(TextWidget, self).__init__(*args, **kwargs) + self.setWidget(QLabel(text, styleSheet="color:white;")) + + +class GraphicsWidget(QGraphicsWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsWidget, self).__init__(*args, **kwargs) +# self.setFlags(self.ItemClipsChildrenToShape) + self.setZValue(999) + layout = QGraphicsGridLayout(self) + for row in range(6): + layout.addItem(CircleWidget("red"), row, 0) + layout.addItem(TextWidget("red"), row, 1) + self.hide() + + def show(self, pos): + self.setGeometry(pos.x(), pos.y(), self.size().width(), + self.size().height()) + super(GraphicsWidget, self).show() +''' + + +class ToolTipItem(QWidget): + + def __init__(self, color, text, parent=None): + super(ToolTipItem, self).__init__(parent) + layout = QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + clabel = QLabel(self) + clabel.setMinimumSize(12, 12) + clabel.setMaximumSize(12, 12) + clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( + color.red(), color.green(), color.blue(), color.alpha())) + layout.addWidget(clabel) + self.textLabel = QLabel(text, self, styleSheet="color:white;") + layout.addWidget(self.textLabel) + + def setText(self, text): + self.textLabel.setText(text) + + +class ToolTipWidget(QWidget): + Cache = {} + + def __init__(self, *args, **kwargs): + super(ToolTipWidget, self).__init__(*args, **kwargs) + self.setAttribute(Qt.WA_StyledBackground, True) + self.setStyleSheet( + "ToolTipWidget{background: rgba(50,50,50,70);}") + layout = QVBoxLayout(self) + self.titleLabel = QLabel(self, styleSheet="color:white;") + layout.addWidget(self.titleLabel) + + def updateUi(self, title, points): + self.titleLabel.setText(title) + for serie, point in points: + if serie not in self.Cache: + item = ToolTipItem( + serie.color(), + (serie.name() or "-") + ":" + str(point.y()), self) + self.layout().addWidget(item) + self.Cache[serie] = item + else: + self.Cache[serie].setText( + (serie.name() or "-") + ":" + str(point.y())) + + +class GraphicsProxyWidget(QGraphicsProxyWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsProxyWidget, self).__init__(*args, **kwargs) + self.setZValue(999) + self.tipWidget = ToolTipWidget() + self.setWidget(self.tipWidget) + self.hide() + + def show(self, title, points, pos): + self.setGeometry(QRectF(pos, self.size())) + self.tipWidget.updateUi(title, points) + super(GraphicsProxyWidget, self).show() + + +class ChartView(QChartView): + + def __init__(self, *args, **kwargs): + super(ChartView, self).__init__(*args, **kwargs) + self.resize(800, 600) + self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.initChart() + + self.toolTipWidget = GraphicsProxyWidget(self._chart) + + # line + self.lineItem = QGraphicsLineItem(self._chart) + self.lineItem.setZValue(998) + self.lineItem.hide() + + # 一些固定计算,减少mouseMoveEvent中的计算量 + # 获取x和y轴的最小最大值 + axisX, axisY = self._chart.axisX(), self._chart.axisY() + self.min_x, self.max_x = axisX.min(), axisX.max() + self.min_y, self.max_y = axisY.min(), axisY.max() + # 坐标系中左上角顶点 + self.point_top = self._chart.mapToPosition( + QPointF(self.min_x, self.max_y)) + # 坐标原点坐标 + self.point_bottom = self._chart.mapToPosition( + QPointF(self.min_x, self.min_y)) + self.step_x = (self.max_x - self.min_x) / (axisX.tickCount() - 1) + + # self.step_y = (self.max_y - self.min_y) / (axisY.tickCount() - 1) + + def mouseMoveEvent(self, event): + super(ChartView, self).mouseMoveEvent(event) + # 把鼠标位置所在点转换为对应的xy值 + x = self._chart.mapToValue(event.pos()).x() + y = self._chart.mapToValue(event.pos()).y() + index = round((x - self.min_x) / self.step_x) + pos_x = self._chart.mapToPosition( + QPointF(index * self.step_x + self.min_x, self.min_y)) + # print(x, pos_x, index, index * self.step_x + self.min_x) + # 得到在坐标系中的所有series的类型和点 + points = [(serie, serie.at(index)) + for serie in self._chart.series() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] + if points: + # 永远在轴上的黑线条 + self.lineItem.setLine(pos_x.x(), self.point_top.y(), + pos_x.x(), self.point_bottom.y()) + self.lineItem.show() + self.toolTipWidget.show("", points, event.pos() + QPoint(20, 20)) + else: + self.toolTipWidget.hide() + self.lineItem.hide() + + def onSeriesHoverd(self, point, state): + if state: + try: + name = self.sender().name() + except: + name = "" + QToolTip.showText(QCursor.pos(), "%s\nx: %s\ny: %s" % + (name, point.x(), point.y())) + + def initChart(self): + self._chart = QChart(title="Line Chart") + self._chart.setAcceptHoverEvents(True) + dataTable = [ + [120, 132, 101, 134, 90, 230, 210], + [220, 182, 191, 234, 290, 330, 310], + [150, 232, 201, 154, 190, 330, 410], + [320, 332, 301, 334, 390, 330, 320], + [820, 932, 901, 934, 1290, 1330, 1320] + ] + for i, data_list in enumerate(dataTable): + series = QLineSeries(self._chart) + for j, v in enumerate(data_list): + series.append(j, v) + series.setName("Series " + str(i)) + series.setPointsVisible(True) # 显示原点 + series.hovered.connect(self.onSeriesHoverd) + self._chart.addSeries(series) + self._chart.createDefaultAxes() # 创建默认的轴 + self._chart.axisX().setTickCount(7) # x轴设置7个刻度 + self._chart.axisY().setTickCount(7) # y轴设置7个刻度 + self._chart.axisY().setRange(0, 1500) # 设置y轴范围 + self.setChart(self._chart) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + app.setStyleSheet("""QToolTip { + border: none; + padding: 5px; + color: white; + background: rgb(50,50,50); + opacity: 100; +}""") + view = ChartView() + view.show() + sys.exit(app.exec_()) diff --git a/图表/PyQtChart/demo/ToolTip2.py b/QChart/ToolTip2.py similarity index 95% rename from 图表/PyQtChart/demo/ToolTip2.py rename to QChart/ToolTip2.py index 3faeb14..cfc797f 100644 --- a/图表/PyQtChart/demo/ToolTip2.py +++ b/QChart/ToolTip2.py @@ -1,220 +1,218 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -''' -Created on 2017年12月23日 -@author: Irony."[讽刺] -@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 -@email: 892768447@qq.com -@file: ToolTip2 -@description: -''' -import sys - -from PyQt5.QtChart import QChartView, QChart, QLineSeries -from PyQt5.QtCore import Qt, QRectF, QPoint, QPointF -from PyQt5.QtGui import QPainter, QCursor -from PyQt5.QtWidgets import QApplication, QGraphicsProxyWidget, QLabel, \ - QWidget, QHBoxLayout, QVBoxLayout, QToolTip, QGraphicsLineItem - - -__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" -__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" -__Version__ = "Version 1.0" - - -''' -class CircleWidget(QGraphicsProxyWidget): - - def __init__(self, color, *args, **kwargs): - super(CircleWidget, self).__init__(*args, **kwargs) - label = QLabel() - label.setMinimumSize(12, 12) - label.setMaximumSize(12, 12) - label.setStyleSheet( - "border:1px solid green;border-radius:6px;background: %s;" % color) - self.setWidget(label) - - -class TextWidget(QGraphicsProxyWidget): - - def __init__(self, text, *args, **kwargs): - super(TextWidget, self).__init__(*args, **kwargs) - self.setWidget(QLabel(text, styleSheet="color:white;")) - - -class GraphicsWidget(QGraphicsWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsWidget, self).__init__(*args, **kwargs) -# self.setFlags(self.ItemClipsChildrenToShape) - self.setZValue(999) - layout = QGraphicsGridLayout(self) - for row in range(6): - layout.addItem(CircleWidget("red"), row, 0) - layout.addItem(TextWidget("red"), row, 1) - self.hide() - - def show(self, pos): - self.setGeometry(pos.x(), pos.y(), self.size().width(), - self.size().height()) - super(GraphicsWidget, self).show() -''' - - -class ToolTipItem(QWidget): - - def __init__(self, color, text, parent=None): - super(ToolTipItem, self).__init__(parent) - layout = QHBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - clabel = QLabel(self) - clabel.setMinimumSize(12, 12) - clabel.setMaximumSize(12, 12) - clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( - color.red(), color.green(), color.blue(), color.alpha())) - layout.addWidget(clabel) - self.textLabel = QLabel(text, self, styleSheet="color:white;") - layout.addWidget(self.textLabel) - - def setText(self, text): - self.textLabel.setText(text) - - -class ToolTipWidget(QWidget): - - Cache = {} - - def __init__(self, *args, **kwargs): - super(ToolTipWidget, self).__init__(*args, **kwargs) - self.setAttribute(Qt.WA_StyledBackground, True) - self.setStyleSheet( - "ToolTipWidget{background: rgba(50,50,50,70);}") - layout = QVBoxLayout(self) - self.titleLabel = QLabel(self, styleSheet="color:white;") - layout.addWidget(self.titleLabel) - - def updateUi(self, title, points): - self.titleLabel.setText(title) - for serie, point in points: - if serie not in self.Cache: - item = ToolTipItem( - serie.color(), - (serie.name() or "-") + ":" + str(point.y()), self) - self.layout().addWidget(item) - self.Cache[serie] = item - else: - self.Cache[serie].setText( - (serie.name() or "-") + ":" + str(point.y())) - - -class GraphicsProxyWidget(QGraphicsProxyWidget): - - def __init__(self, *args, **kwargs): - super(GraphicsProxyWidget, self).__init__(*args, **kwargs) - self.setZValue(999) - self.tipWidget = ToolTipWidget() - self.setWidget(self.tipWidget) - self.hide() - - def show(self, title, points, pos): - self.setGeometry(QRectF(pos, self.size())) - self.tipWidget.updateUi(title, points) - super(GraphicsProxyWidget, self).show() - - -class ChartView(QChartView): - - def __init__(self, *args, **kwargs): - super(ChartView, self).__init__(*args, **kwargs) - self.resize(800, 600) - self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 - self.initChart() - - self.toolTipWidget = GraphicsProxyWidget(self._chart) - - # line - self.lineItem = QGraphicsLineItem(self._chart) - self.lineItem.setZValue(998) - self.lineItem.hide() - - # 一些固定计算,减少mouseMoveEvent中的计算量 - # 获取x和y轴的最小最大值 - axisX, axisY = self._chart.axisX(), self._chart.axisY() - self.min_x, self.max_x = axisX.min(), axisX.max() - self.min_y, self.max_y = axisY.min(), axisY.max() - # 坐标系中左上角顶点 - self.point_top = self._chart.mapToPosition( - QPointF(self.min_x, self.max_y)) - # 坐标原点坐标 - self.point_bottom = self._chart.mapToPosition( - QPointF(self.min_x, self.min_y)) - self.step_x = (self.max_x - self.min_x) / (axisX.tickCount() - 1) -# self.step_y = (self.max_y - self.min_y) / (axisY.tickCount() - 1) - - def mouseMoveEvent(self, event): - super(ChartView, self).mouseMoveEvent(event) - # 把鼠标位置所在点转换为对应的xy值 - x = self._chart.mapToValue(event.pos()).x() - y = self._chart.mapToValue(event.pos()).y() - index = round((x - self.min_x) / self.step_x) -# print(x, pos_x, index, index * self.step_x + self.min_x) - # 得到在坐标系中的所有series的类型和点 - points = [(serie, serie.at(index)) - for serie in self._chart.series() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] - if points: - # 跟随鼠标的黑线条 - self.lineItem.setLine(event.pos().x(), self.point_top.y(), - event.pos().x(), self.point_bottom.y()) - self.lineItem.show() - self.toolTipWidget.show("", points, event.pos() + QPoint(20, 20)) - else: - self.toolTipWidget.hide() - self.lineItem.hide() - - def onSeriesHoverd(self, point, state): - if state: - try: - name = self.sender().name() - except: - name = "" - QToolTip.showText(QCursor.pos(), "%s\nx: %s\ny: %s" % - (name, point.x(), point.y())) - - def initChart(self): - self._chart = QChart(title="Line Chart") - self._chart.setAcceptHoverEvents(True) - dataTable = [ - [120, 132, 101, 134, 90, 230, 210], - [220, 182, 191, 234, 290, 330, 310], - [150, 232, 201, 154, 190, 330, 410], - [320, 332, 301, 334, 390, 330, 320], - [820, 932, 901, 934, 1290, 1330, 1320] - ] - for i, data_list in enumerate(dataTable): - series = QLineSeries(self._chart) - for j, v in enumerate(data_list): - series.append(j, v) - series.setName("Series " + str(i)) - series.setPointsVisible(True) # 显示原点 - series.hovered.connect(self.onSeriesHoverd) - self._chart.addSeries(series) - self._chart.createDefaultAxes() # 创建默认的轴 - self._chart.axisX().setTickCount(7) # x轴设置7个刻度 - self._chart.axisY().setTickCount(7) # y轴设置7个刻度 - self._chart.axisY().setRange(0, 1500) # 设置y轴范围 - self.setChart(self._chart) - - -if __name__ == "__main__": - app = QApplication(sys.argv) - app.setStyleSheet("""QToolTip { - border: none; - padding: 5px; - color: white; - background: rgb(50,50,50); - opacity: 100; -}""") - view = ChartView() - view.show() - sys.exit(app.exec_()) +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Created on 2017年12月23日 +@author: Irony."[讽刺] +@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 +@email: 892768447@qq.com +@file: ToolTip2 +@description: +''' +import sys + +from PyQt5.QtChart import QChartView, QChart, QLineSeries +from PyQt5.QtCore import Qt, QRectF, QPoint, QPointF +from PyQt5.QtGui import QPainter, QCursor +from PyQt5.QtWidgets import QApplication, QGraphicsProxyWidget, QLabel, \ + QWidget, QHBoxLayout, QVBoxLayout, QToolTip, QGraphicsLineItem + +__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" +__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]" +__Version__ = "Version 1.0" + +''' +class CircleWidget(QGraphicsProxyWidget): + + def __init__(self, color, *args, **kwargs): + super(CircleWidget, self).__init__(*args, **kwargs) + label = QLabel() + label.setMinimumSize(12, 12) + label.setMaximumSize(12, 12) + label.setStyleSheet( + "border:1px solid green;border-radius:6px;background: %s;" % color) + self.setWidget(label) + + +class TextWidget(QGraphicsProxyWidget): + + def __init__(self, text, *args, **kwargs): + super(TextWidget, self).__init__(*args, **kwargs) + self.setWidget(QLabel(text, styleSheet="color:white;")) + + +class GraphicsWidget(QGraphicsWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsWidget, self).__init__(*args, **kwargs) +# self.setFlags(self.ItemClipsChildrenToShape) + self.setZValue(999) + layout = QGraphicsGridLayout(self) + for row in range(6): + layout.addItem(CircleWidget("red"), row, 0) + layout.addItem(TextWidget("red"), row, 1) + self.hide() + + def show(self, pos): + self.setGeometry(pos.x(), pos.y(), self.size().width(), + self.size().height()) + super(GraphicsWidget, self).show() +''' + + +class ToolTipItem(QWidget): + + def __init__(self, color, text, parent=None): + super(ToolTipItem, self).__init__(parent) + layout = QHBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + clabel = QLabel(self) + clabel.setMinimumSize(12, 12) + clabel.setMaximumSize(12, 12) + clabel.setStyleSheet("border-radius:6px;background: rgba(%s,%s,%s,%s);" % ( + color.red(), color.green(), color.blue(), color.alpha())) + layout.addWidget(clabel) + self.textLabel = QLabel(text, self, styleSheet="color:white;") + layout.addWidget(self.textLabel) + + def setText(self, text): + self.textLabel.setText(text) + + +class ToolTipWidget(QWidget): + Cache = {} + + def __init__(self, *args, **kwargs): + super(ToolTipWidget, self).__init__(*args, **kwargs) + self.setAttribute(Qt.WA_StyledBackground, True) + self.setStyleSheet( + "ToolTipWidget{background: rgba(50,50,50,70);}") + layout = QVBoxLayout(self) + self.titleLabel = QLabel(self, styleSheet="color:white;") + layout.addWidget(self.titleLabel) + + def updateUi(self, title, points): + self.titleLabel.setText(title) + for serie, point in points: + if serie not in self.Cache: + item = ToolTipItem( + serie.color(), + (serie.name() or "-") + ":" + str(point.y()), self) + self.layout().addWidget(item) + self.Cache[serie] = item + else: + self.Cache[serie].setText( + (serie.name() or "-") + ":" + str(point.y())) + + +class GraphicsProxyWidget(QGraphicsProxyWidget): + + def __init__(self, *args, **kwargs): + super(GraphicsProxyWidget, self).__init__(*args, **kwargs) + self.setZValue(999) + self.tipWidget = ToolTipWidget() + self.setWidget(self.tipWidget) + self.hide() + + def show(self, title, points, pos): + self.setGeometry(QRectF(pos, self.size())) + self.tipWidget.updateUi(title, points) + super(GraphicsProxyWidget, self).show() + + +class ChartView(QChartView): + + def __init__(self, *args, **kwargs): + super(ChartView, self).__init__(*args, **kwargs) + self.resize(800, 600) + self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 + self.initChart() + + self.toolTipWidget = GraphicsProxyWidget(self._chart) + + # line + self.lineItem = QGraphicsLineItem(self._chart) + self.lineItem.setZValue(998) + self.lineItem.hide() + + # 一些固定计算,减少mouseMoveEvent中的计算量 + # 获取x和y轴的最小最大值 + axisX, axisY = self._chart.axisX(), self._chart.axisY() + self.min_x, self.max_x = axisX.min(), axisX.max() + self.min_y, self.max_y = axisY.min(), axisY.max() + # 坐标系中左上角顶点 + self.point_top = self._chart.mapToPosition( + QPointF(self.min_x, self.max_y)) + # 坐标原点坐标 + self.point_bottom = self._chart.mapToPosition( + QPointF(self.min_x, self.min_y)) + self.step_x = (self.max_x - self.min_x) / (axisX.tickCount() - 1) + + # self.step_y = (self.max_y - self.min_y) / (axisY.tickCount() - 1) + + def mouseMoveEvent(self, event): + super(ChartView, self).mouseMoveEvent(event) + # 把鼠标位置所在点转换为对应的xy值 + x = self._chart.mapToValue(event.pos()).x() + y = self._chart.mapToValue(event.pos()).y() + index = round((x - self.min_x) / self.step_x) + # print(x, pos_x, index, index * self.step_x + self.min_x) + # 得到在坐标系中的所有series的类型和点 + points = [(serie, serie.at(index)) + for serie in self._chart.series() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] + if points: + # 跟随鼠标的黑线条 + self.lineItem.setLine(event.pos().x(), self.point_top.y(), + event.pos().x(), self.point_bottom.y()) + self.lineItem.show() + self.toolTipWidget.show("", points, event.pos() + QPoint(20, 20)) + else: + self.toolTipWidget.hide() + self.lineItem.hide() + + def onSeriesHoverd(self, point, state): + if state: + try: + name = self.sender().name() + except: + name = "" + QToolTip.showText(QCursor.pos(), "%s\nx: %s\ny: %s" % + (name, point.x(), point.y())) + + def initChart(self): + self._chart = QChart(title="Line Chart") + self._chart.setAcceptHoverEvents(True) + dataTable = [ + [120, 132, 101, 134, 90, 230, 210], + [220, 182, 191, 234, 290, 330, 310], + [150, 232, 201, 154, 190, 330, 410], + [320, 332, 301, 334, 390, 330, 320], + [820, 932, 901, 934, 1290, 1330, 1320] + ] + for i, data_list in enumerate(dataTable): + series = QLineSeries(self._chart) + for j, v in enumerate(data_list): + series.append(j, v) + series.setName("Series " + str(i)) + series.setPointsVisible(True) # 显示原点 + series.hovered.connect(self.onSeriesHoverd) + self._chart.addSeries(series) + self._chart.createDefaultAxes() # 创建默认的轴 + self._chart.axisX().setTickCount(7) # x轴设置7个刻度 + self._chart.axisY().setTickCount(7) # y轴设置7个刻度 + self._chart.axisY().setRange(0, 1500) # 设置y轴范围 + self.setChart(self._chart) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + app.setStyleSheet("""QToolTip { + border: none; + padding: 5px; + color: white; + background: rgb(50,50,50); + opacity: 100; +}""") + view = ChartView() + view.show() + sys.exit(app.exec_()) diff --git a/树结构/QTreeWidget/Json生成QTreeWidget/data.json b/QTreeWidget/Data/data.json similarity index 93% rename from 树结构/QTreeWidget/Json生成QTreeWidget/data.json rename to QTreeWidget/Data/data.json index 09f79a1..0957385 100644 --- a/树结构/QTreeWidget/Json生成QTreeWidget/data.json +++ b/QTreeWidget/Data/data.json @@ -1,56 +1,56 @@ -[ - { - "name": "仪表盘", - "icon": "xxx.png" - }, - { - "name": "微信管理", - "icon": "weixin.png", - "badge": [ - "火爆", - "#F8AC54" - ], - "items": [ - { - "name": "爬虫项目管理", - "icon": "xxx.png", - "badge": [ - "推荐", - "#23C6C9" - ], - "items": [ - { - "name": "腾讯课堂" - }, - { - "name": "淘宝" - }, - { - "name": "京东" - }, - { - "name": "天猫" - }, - { - "name": "拉钩" - }, - { - "name": "BOSS直聘" - } - ] - } - ] - }, - { - "name": "爬虫部署管理", - "icon": "xxx.png" - }, - { - "name": "爬虫监控管理", - "icon": "xxx.png" - }, - { - "name": "PyQt", - "url": "https://github.com/892768447/PyQt" - } -] +[ + { + "name": "仪表盘", + "icon": "xxx.png" + }, + { + "name": "微信管理", + "icon": "Data/weixin.png", + "badge": [ + "火爆", + "#F8AC54" + ], + "items": [ + { + "name": "爬虫项目管理", + "icon": "xxx.png", + "badge": [ + "推荐", + "#23C6C9" + ], + "items": [ + { + "name": "腾讯课堂" + }, + { + "name": "淘宝" + }, + { + "name": "京东" + }, + { + "name": "天猫" + }, + { + "name": "拉钩" + }, + { + "name": "BOSS直聘" + } + ] + } + ] + }, + { + "name": "爬虫部署管理", + "icon": "xxx.png" + }, + { + "name": "爬虫监控管理", + "icon": "xxx.png" + }, + { + "name": "PyQt", + "url": "https://github.com/892768447/PyQt" + } +] diff --git a/树结构/QTreeWidget/Json生成QTreeWidget/weixin.png b/QTreeWidget/Data/weixin.png similarity index 100% rename from 树结构/QTreeWidget/Json生成QTreeWidget/weixin.png rename to QTreeWidget/Data/weixin.png diff --git a/树结构/QTreeWidget/Json生成QTreeWidget/Json生成树形结构.py b/QTreeWidget/ParsingJson.py similarity index 98% rename from 树结构/QTreeWidget/Json生成QTreeWidget/Json生成树形结构.py rename to QTreeWidget/ParsingJson.py index 6439f87..0ff2ddc 100644 --- a/树结构/QTreeWidget/Json生成QTreeWidget/Json生成树形结构.py +++ b/QTreeWidget/ParsingJson.py @@ -6,7 +6,7 @@ Created on 2018年4月8日 @author: Irony @site: https://pyqt5.com, https://github.com/892768447 @email: 892768447@qq.com -@file: +@file: ParsingJson @description: """ import json @@ -148,5 +148,5 @@ QTreeView:branch:selected { """) w = JsonTreeWidget() w.show() - w.loadData('data.json') + w.loadData('Data/data.json') sys.exit(app.exec_()) diff --git a/QTreeWidget/README.md b/QTreeWidget/README.md index e69de29..5317d97 100644 --- a/QTreeWidget/README.md +++ b/QTreeWidget/README.md @@ -0,0 +1,8 @@ +# QTreeWidget + +## 1、通过json数据生成树形结构 +[运行 ParsingJson.py](ParsingJson.py) + +解析每一层json数据中的list + +![ParsingJson](ScreenShot/ParsingJson.png) \ No newline at end of file diff --git a/树结构/QTreeWidget/Json生成QTreeWidget/ScreenShot/Json生成树形结构.png b/QTreeWidget/ScreenShot/ParsingJson.png similarity index 100% rename from 树结构/QTreeWidget/Json生成QTreeWidget/ScreenShot/Json生成树形结构.png rename to QTreeWidget/ScreenShot/ParsingJson.png diff --git a/图表/PyQtChart/ChartView/ChartView.py b/Test/ChartView/ChartView.py similarity index 100% rename from 图表/PyQtChart/ChartView/ChartView.py rename to Test/ChartView/ChartView.py diff --git a/图表/PyQtChart/ChartView/ChatWidget.py b/Test/ChartView/ChatWidget.py similarity index 100% rename from 图表/PyQtChart/ChartView/ChatWidget.py rename to Test/ChartView/ChatWidget.py diff --git a/图表/PyQtChart/ChartView/loading.gif b/Test/ChartView/loading.gif similarity index 100% rename from 图表/PyQtChart/ChartView/loading.gif rename to Test/ChartView/loading.gif diff --git a/图表/PyQtChart/ChartView/分类/折线图/堆叠折线图.json b/Test/ChartView/分类/折线图/堆叠折线图.json similarity index 100% rename from 图表/PyQtChart/ChartView/分类/折线图/堆叠折线图.json rename to Test/ChartView/分类/折线图/堆叠折线图.json diff --git a/图表/PyQtChart/ChartView/分类/柱状图/堆叠柱状图.json b/Test/ChartView/分类/柱状图/堆叠柱状图.json similarity index 100% rename from 图表/PyQtChart/ChartView/分类/柱状图/堆叠柱状图.json rename to Test/ChartView/分类/柱状图/堆叠柱状图.json diff --git a/图表/README.md b/图表/README.md deleted file mode 100644 index 364b611..0000000 --- a/图表/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# 图表 - -## [1、PyQtChart](PyQtChart/) - -### 1. [折线图](PyQtChart/charts/line/LineStack.py) -仿照 [line-stack](http://echarts.baidu.com/demo.html#line-stack) - -![截图](PyQtChart/charts/line/ScreenShot/LineStack.gif) - -### 2. [柱状图](PyQtChart/charts/bar/BarStack.py) -仿照 [bar-stack](http://echarts.baidu.com/demo.html#bar-stack) - -![截图](PyQtChart/charts/bar/ScreenShot/BarStack.gif) - -### 3. [LineChart](PyQtChart/demo/LineChart.py) -![截图](PyQtChart/demo/ScreenShot/LineChart.png) - -### 4. [LineChart自定义xy轴](PyQtChart/demo/LineChart自定义xy轴.py) -![截图](PyQtChart/demo/ScreenShot/LineChart自定义xy轴.png) - -### 5. [ToolTip提示](PyQtChart/demo/ToolTip.py) -![截图](PyQtChart/demo/ScreenShot/ToolTip.gif) \ No newline at end of file diff --git a/树结构/README.md b/树结构/README.md deleted file mode 100644 index 44a13a5..0000000 --- a/树结构/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# 树结构 - -## [1、QTreeWidget](QTreeWidget/) - -### 1.通过json数据生成树形结构 -emmmmmm,原理就是那样,,解析每一层json数据中的list,美化就不想弄了. - -![截图](QTreeWidget/Json生成QTreeWidget/ScreenShot/Json生成树形结构.png) \ No newline at end of file