| 104 | |
| 105 | |
| 106 | class ChartView(QChartView): |
| 107 | |
| 108 | def __init__(self, *args, **kwargs): |
| 109 | super(ChartView, self).__init__(*args, **kwargs) |
| 110 | self.resize(800, 600) |
| 111 | self.setRenderHint(QPainter.Antialiasing) # 抗锯齿 |
| 112 | self.initChart() |
| 113 | |
| 114 | # 提示widget |
| 115 | self.toolTipWidget = GraphicsProxyWidget(self._chart) |
| 116 | |
| 117 | # line 宽度需要调整 |
| 118 | self.lineItem = QGraphicsLineItem(self._chart) |
| 119 | pen = QPen(Qt.gray) |
| 120 | self.lineItem.setPen(pen) |
| 121 | self.lineItem.setZValue(998) |
| 122 | self.lineItem.hide() |
| 123 | |
| 124 | # 一些固定计算,减少mouseMoveEvent中的计算量 |
| 125 | # 获取x和y轴的最小最大值 |
| 126 | axisX, axisY = self._chart.axisX(), self._chart.axisY() |
| 127 | self.category_len = len(axisX.categories()) |
| 128 | self.min_x, self.max_x = -0.5, self.category_len - 0.5 |
| 129 | self.min_y, self.max_y = axisY.min(), axisY.max() |
| 130 | # 坐标系中左上角顶点 |
| 131 | self.point_top = self._chart.mapToPosition( |
| 132 | QPointF(self.min_x, self.max_y)) |
| 133 | |
| 134 | def mouseMoveEvent(self, event): |
| 135 | super(ChartView, self).mouseMoveEvent(event) |
| 136 | pos = event.pos() |
| 137 | # 把鼠标位置所在点转换为对应的xy值 |
| 138 | x = self._chart.mapToValue(pos).x() |
| 139 | y = self._chart.mapToValue(pos).y() |
| 140 | index = round(x) |
| 141 | # 得到在坐标系中的所有bar的类型和点 |
| 142 | serie = self._chart.series()[0] |
| 143 | bars = [(bar, bar.at(index)) |
| 144 | for bar in serie.barSets() if self.min_x <= x <= self.max_x and self.min_y <= y <= self.max_y] |
| 145 | # print(bars) |
| 146 | if bars: |
| 147 | right_top = self._chart.mapToPosition( |
| 148 | QPointF(self.max_x, self.max_y)) |
| 149 | # 等分距离比例 |
| 150 | step_x = round( |
| 151 | (right_top.x() - self.point_top.x()) / self.category_len) |
| 152 | posx = self._chart.mapToPosition(QPointF(x, self.min_y)) |
| 153 | self.lineItem.setLine(posx.x(), self.point_top.y(), |
| 154 | posx.x(), posx.y()) |
| 155 | self.lineItem.show() |
| 156 | try: |
| 157 | title = self.categories[index] |
| 158 | except: |
| 159 | title = "" |
| 160 | t_width = self.toolTipWidget.width() |
| 161 | t_height = self.toolTipWidget.height() |
| 162 | # 如果鼠标位置离右侧的距离小于tip宽度 |
| 163 | x = pos.x() - t_width if self.width() - \ |