Я создал GUI в pyside2
со встроенным matplotlib
холстом. Я планирую отобразить много информации на этом холсте, поэтому мне нужно больше вертикального пространства. Я подумал, что мог бы поместить холст внутри QScrollArea
и создать «высокую» фигуру с несколькими подзаговорами друг над другом.
Этот ответ приближается к тому, что я хочу, но я не вообще не хочу горизонтальной прокрутки. Скорее, Я бы хотел, чтобы мой холст расширялся / сжимался в соответствии с GUI, полностью занимая доступное горизонтальное пространство внутри QScrollArea
, но при этом позволяя только вертикальную прокрутку рисунка.
Следующий код является MRE без полос прокрутки:
import sys
from PySide2.QtCore import Qt
from PySide2.QtWidgets import (QApplication, QHBoxLayout, QMainWindow,
QPushButton, QVBoxLayout, QWidget)
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as Canvas,
NavigationToolbar2QT as Navbar)
from matplotlib.pyplot import Figure
class MyApp(QMainWindow):
def __init__(self) -> None:
super().__init__()
# Main Window setup
self.showMaximized()
self.frame = QWidget(self)
self.setCentralWidget(self.frame)
main_layout = QHBoxLayout()
self.frame.setLayout(main_layout)
# Buttons (left column)
buttons_row = QHBoxLayout()
self.plot_above_button = QPushButton(self, text='Plot Data Above')
self.plot_above_button.clicked.connect(self.plot_above)
buttons_row.addWidget(self.plot_above_button)
self.plot_below_button = QPushButton(self, text='Plot Data Below')
self.plot_below_button.clicked.connect(self.plot_below)
buttons_row.addWidget(self.plot_below_button)
main_layout.addLayout(buttons_row)
# Plot (right column)
right_column = QVBoxLayout()
self.fig = Figure(facecolor='white')
self.ax1 = self.fig.add_axes([0.1, 0.3, 0.8, 0.7])
self.ax2 = self.fig.add_axes([0.1, 0.1, 0.8, 0.1])
self.canvas = Canvas(self.fig)
self.canvas.setParent(self)
right_column.addWidget(self.canvas)
right_column.addWidget(Navbar(self.canvas, self.frame))
main_layout.addLayout(right_column)
def plot_above(self):
self.ax1.plot([1, 2], [3, 4])
self.canvas.draw()
def plot_below(self):
self.ax2.plot([1, 2], [3, 4])
self.canvas.draw()
if __name__ == '__main__':
app = QApplication()
gui = MyApp()
gui.show()
sys.exit(app.exec_())
И это GUI, которое я вижу, когда выполняю код выше:
Как видите, холст занимает все доступное пространство, по вертикали и по горизонтали. За исключением отсутствия вертикальной полосы прокрутки, это именно то, что я хочу.
Теперь, если я попытаюсь поместить self.canvas
в QScrollArea
, добавив эти строки в мой код:
from PySide2.QtWidgets import QScrollArea # additional import
# ...
self.canvas.setParent(self) # this is old code
# new code starts here
scroll_area = QScrollArea()
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll_area.horizontalScrollBar().setEnabled(False)
scroll_area.setWidget(self.canvas)
right_column.addWidget(scroll_area)
right_column.addWidget(Navbar(self.canvas, self.frame)) # this is old code
# ...
Теперь я получаю:
Вместо автоматической настройки своего размера фигура просто «сидит» внутри QScrollArea
, инициализирована со значением figsize по умолчанию.
Я также попытался вручную изменить размер фигуры, написав, например:
self.fig = Figure(facecolor='white', figsize=(11, 12))
, что дает мне:
Это очень близко к тому, что я хочу, но также и очень забавно: я эмпирически выбрал figsize (11, 12)
на основе того, как холст выглядит на моем экране, но эти значения могут отличаться в другом экран или если я добавлю дополнительные виджеты на левой стороне. Размер холста также не изменяется вместе с основным окном.
Есть ли способ добиться того, чего я хочу?