PyQt Как увидеть часть графика, ушедшую за край области видимости при увеличении масштаба?

При увеличении масштаба часть изображения (графика) уходит за край области видимости. Увидеть эту ушедшую часть теоретически можно (1) двигая ползунок прокрутки (скролл) (2) двигая стрелками (3) на онлайн картах есть drag-and-drop, но это не наш случай.

По некоторым причинам (отсутствует мышь, есть только клавиатура) нужен способ 'двигаем график стрелками'. Как это реализовать?

Кроме того, стартовое изображение графика должно умещаться на экране полностью.

from PySide6.QtWidgets import QWidget, QApplication, QHBoxLayout, QScrollArea, QVBoxLayout
from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis
from PySide6.QtCore import QPointF
from PySide6.QtGui import QPainter, Qt
import math
import sys


class Charts(QWidget):
    def __init__(self, parent=None):
        super(Charts, self).__init__(parent)
        self.zoomFactor = 1.1
        self.zoom_value = 0
        self.chart = QChart()
        self.series1 = QLineSeries()
        for i in range(0,2500,1):
            self.series1.append([QPointF(i, math.sin(i * 0.01))])
        self.chart.addSeries(self.series1)
        y_axis = QValueAxis()
        y_axis.setRange(-1, 1)
        y_axis.setTickType(QValueAxis.TickType.TicksDynamic)
        y_axis.setTickInterval(20)
        x_axis = QValueAxis()
        x_axis.setRange(1, 2500)
        x_axis.setTickInterval(100)
        x_axis.setTickType(QValueAxis.TickType.TicksDynamic)
        self.chart.addAxis(x_axis, Qt.AlignmentFlag.AlignBottom)
        self.chart.addAxis(y_axis, Qt.AlignmentFlag.AlignLeft)
        self.chart.legend().hide()
        self.chart.createDefaultAxes()
        self.chartview = QChartView(self.chart)
        self.chartview.setRenderHint(QPainter.Antialiasing)
        vbox = QVBoxLayout()
        vbox.addWidget(self.chartview)
        self.setLayout(vbox)

    def keyPressEvent(self, keyEvent):
        key = keyEvent.key()
        if key == Qt.Key_W and self.zoom_value < 10:
            self.chartview.chart().zoom(self.zoomFactor)
            self.zoom_value = self.zoom_value + 1
        elif key == Qt.Key_S and self.zoom_value > 0:
            self.chartview.chart().zoom(1 / self.zoomFactor)
            self.zoom_value = self.zoom_value - 1


if __name__ == '__main__':
    app = QApplication(sys.argv)
    charts = Charts()
    charts.show()
    sys.exit(app.exec())

Ответы (1 шт):

Автор решения: Garp

Тут увеличение только по одной оси, добавить вторую несложно. Кроме того, обходимся без zoom(), что даёт больше возможностей.

from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
from PySide6.QtCharts import *
import math
import sys



class Charts(QWidget):
    def __init__(self, parent=None):
        super(Charts, self).__init__(parent)
        self.chart = QChart()
        self.series = QLineSeries()
        self.x_start = 0
        self.x_stop = 100
        self.zoomFactor = self.x_stop / 20
        self.zoom_value = 0
        for i in range(self.x_start, self.x_stop, 1):
            self.series.append([QPointF(i, math.cos(i * 0.1))])
        self.chart.addSeries(self.series)
        self.y_axis = QValueAxis()
        self.y_axis.setRange(-1, 1)
        self.y_axis.setTickType(QValueAxis.TickType.TicksDynamic)
        self.y_axis.setTickInterval(5)
        self.x_axis = QValueAxis()
        self.x_axis.setRange(self.x_start, self.x_stop)
        self.x_axis.setTickInterval(5)
        self.x_axis.setTickType(QValueAxis.TickType.TicksDynamic)
        self.chart.addAxis(self.x_axis, Qt.AlignmentFlag.AlignBottom)
        self.chart.addAxis(self.y_axis, Qt.AlignmentFlag.AlignLeft)
        self.series.attachAxis(self.x_axis)
        self.series.attachAxis(self.y_axis)
        self.chart.legend().hide()
        self.chartview = QChartView(self.chart)
        self.chartview.setRenderHint(QPainter.Antialiasing)
        vbox = QVBoxLayout()
        vbox.addWidget(self.chartview)
        self.setLayout(vbox)

    def keyPressEvent(self, keyEvent):
        key = keyEvent.key()
        if key == Qt.Key_W and self.zoom_value < 10:
            self.x_start = self.x_start + self.zoomFactor
            self.x_stop = self.x_stop - self.zoomFactor
            self.x_axis.setRange(self.x_start, self.x_stop)
            self.zoom_value = self.zoom_value + 1
        elif key == Qt.Key_S and self.zoom_value > 0:
            self.x_start = self.x_start - self.zoomFactor
            self.x_stop = self.x_stop + self.zoomFactor
            self.x_axis.setRange(self.x_start, self.x_stop)
            self.zoom_value = self.zoom_value - 1
        elif key == Qt.Key_A and self.zoom_value > 0:          # to left
            self.x_start = self.x_start - self.zoomFactor
            self.x_stop = self.x_stop - self.zoomFactor
            self.x_axis.setRange(self.x_start, self.x_stop)
        if key == Qt.Key_D and self.zoom_value < 10:           # to right
            self.x_start = self.x_start + self.zoomFactor
            self.x_stop = self.x_stop + self.zoomFactor
            self.x_axis.setRange(self.x_start, self.x_stop)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    charts = Charts()
    charts.show()
    sys.exit(app.exec())
→ Ссылка