Динамическое изменение масштаба графика, QChart
Можно ли динамически (крутим spinbox) менять масштаб графика?
Минимально воспроизводимый пример (тут только оси, собственно графика тут нет, т.к. не нужен):
from PySide6.QtWidgets import *
from PySide6.QtCharts import *
from PySide6.QtGui import *
import sys
class Main(QWidget):
def __init__(self):
super().__init__()
chart = MyChart()
spinbox = MySpinBox()
vbox = QVBoxLayout()
vbox.addWidget(chart)
vbox.addWidget(spinbox)
self.setLayout(vbox)
class MyChart(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
chart_view = QChartView()
chart_view.setRubberBand(QChartView.RectangleRubberBand)
chart_view.setRenderHint(QPainter.Antialiasing)
layout.addWidget(chart_view)
chart = QChart()
chart.setAnimationOptions(QChart.SeriesAnimations)
series = QLineSeries()
chart.addSeries(series)
axis_x = QValueAxis()
chart.addAxis(axis_x, Qt.AlignBottom)
series.attachAxis(axis_x)
axis_y = QValueAxis()
chart.addAxis(axis_y, Qt.AlignLeft)
series.attachAxis(axis_y)
chart_view.setChart(chart)
self.setLayout(layout)
class MySpinBox(QWidget):
def __init__(self):
super().__init__()
self.chart = MyChart() # экземпляр класса графика, через него надо менять масштаб
widget = QSpinBox()
widget.setMinimum(-100)
widget.setMaximum(100)
widget.setSingleStep(1)
widget.valueChanged.connect(self.value_changed)
vbox = QVBoxLayout()
vbox.addWidget(widget)
self.setLayout(vbox)
def value_changed(self, i):
# Тут надо писать логику изменения масштаба и что-то делать с self.chart
print(i)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Пожалуйста, всегда предоставляйте минимально-воспроизводимый пример, который демонстрирует проблему. График также должен быть. И было бы хорошо, если вы как-то показали то, что вы хотите получить.
Ваши изменения и дополнения должны быть в теле вопроса, а не в комментариях.
Я не уверен, что правильно понимаю вас, но мне кажется, что, как вариант, это может выглядеть примерно так:
import sys
''' # PySide6
from PySide6.QtCore import *
from PySide6.QtWidgets import *
from PySide6.QtCharts import *
from PySide6.QtGui import *
'''
from PyQt5 import QtWidgets, QtGui, QtCore # PyQt5
from PyQt5.Qt import *
from PyQt5.QtChart import *
class MySpinBox(QWidget):
def __init__(self):
super().__init__()
# ? # экземпляр класса графика, через него надо менять масштаб
# ? self.chart = MyChart()
self.spinBox = QSpinBox()
self.spinBox.setRange(-15, 15)
vbox = QVBoxLayout(self)
vbox.addWidget(self.spinBox)
class MyChart(QWidget):
def __init__(self):
super().__init__()
self.chart_view = QChartView()
self.chart_view.setRubberBand(QChartView.RectangleRubberBand)
self.chart_view.setRenderHint(QPainter.Antialiasing)
chart = QChart()
chart.setAnimationOptions(QChart.SeriesAnimations)
series = QLineSeries()
mas = [
1.33, 1.15, 1.55, 1.65, 1.64, 1.91, 1.33, 2.3, 1.5, 1.35,
2.52, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1, 1.33, 1.15,
1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77,
1.7, 1.87, 2.7, 1.55, 1.73, 2.1,
]
for i in range(0, len(mas)):
series.append(QtCore.QPointF(i, mas[i]))
chart.addSeries(series)
self.axis_x = QValueAxis()
chart.addAxis(self.axis_x, Qt.AlignBottom)
series.attachAxis(self.axis_x)
self.axis_y = QValueAxis()
chart.addAxis(self.axis_y, Qt.AlignLeft)
series.attachAxis(self.axis_y)
self.chart_view.setChart(chart)
layout = QVBoxLayout(self)
layout.addWidget(self.chart_view)
chart.legend().setMarkerShape(QLegend.MarkerShapeCircle);
self.chart_view.setRenderHint(QPainter.Antialiasing);
self.chart_view.setRubberBand(QChartView.RectangleRubberBand);
class Main(QWidget):
def __init__(self):
super().__init__()
self.chart = MyChart()
self.mySpinBox = MySpinBox()
self.mySpinBox.spinBox.valueChanged.connect(self.value_changed)
vbox = QVBoxLayout(self)
vbox.addWidget(self.chart)
vbox.addWidget(self.mySpinBox)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.value = 0 # +
self.zoomFactor = 1.1 # +
def value_changed(self, value):
_value = value - self.value
self.value = value
if _value == 1: # or Qt.Key_Plus:
self.chart.chart_view.chart().zoom(self.zoomFactor)
elif _value == -1: # or Qt.Key_Minus:
self.chart.chart_view.chart().zoom(1 / self.zoomFactor)
#+ or
def keyPressEvent(self, keyEvent):
key = keyEvent.key()
if key == Qt.Key_Equal: # ----> `=`
self.chart.chart_view.chart().zoomReset()
self.mySpinBox.spinBox.setValue(0)
# ...
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec())



