在QScrollWidget中使用PyQt4和matplotlib

1 投票
1 回答
739 浏览
提问于 2025-04-17 14:46

我在做一个 PyQt4 应用程序,里面嵌入了 matplotlib。现在遇到一个问题,就是每次我动态添加一个子图到图形中,所有的图形就会被压缩得很紧。为了解决这个问题,我想把图形放到一个 QScrollArea 里,但好像并没有成功。下面是我认为可以解决这个问题的一个例子:

import os
os.environ['QT_API'] = 'pyside'

from PySide.QtGui   import *
from PySide.QtCore  import *

import matplotlib

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure                  import Figure


class Canvas(FigureCanvasQTAgg):

    def __init__(self, parent=None):
        self.figure = Figure()
        super(Canvas, self).__init__(self.figure)

        ax = self.figure.add_subplot(1,1,1)
        ax.plot([1,2,3])
        self.draw()

    def add_subplot(self, data=[]):
        rows = len(self.figure.axes) + 1
        for index, axes in enumerate(self.figure.axes, start=1):
            axes.change_geometry(rows, 1, index)

        ax = self.figure.add_subplot(rows, 1, index+1)
        ax.plot(data)

        self.draw()

class Main(QWidget):

    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        self.canvas = QScrollArea(self)
        self.canvas.setWidget(Canvas(self))
        self.canvas.setWidgetResizable(True)

        for x in range(5):
            self.canvas.widget().add_subplot()

        layout = QVBoxLayout(self)
        layout.addWidget(self.canvas)


app = QApplication([])
main = Main()
main.show()
app.exec_()

你有没有注意到,所有的图表都挤在一起,显示在同一个可见的空间里?我希望能滚动查看其他的图表,而不是让它们都挤在一起。我不太确定该怎么做。

有没有人知道怎么解决这个问题,或者有没有其他的方法可以做到这一点?

1 个回答

2

解决这个问题可以分为两个步骤:

第一步是取消滚动区域的自动调整大小,这样就能显示滚动条。把这一行:

self.canvas.setWidgetResizable(True)

改成:

self.canvas.setWidgetResizable(False)

第二步是在添加子图的时候,调整图形的高度,因为画布会根据图形的大小来决定它的高度:

def add_subplot(self, data=[]):
    rows = len(self.figure.axes) + 1
    for index, axes in enumerate(self.figure.axes, start=1):
        axes.change_geometry(rows, 1, index)

    ax = self.figure.add_subplot(rows, 1, index+1)
    ax.plot(data)
    self.figure.set_figheight(self.figure.get_figheight()*1.25)
    self.draw()

在主程序中,你需要告诉PySide,让它知道要在滚动区域中调整小部件的大小:

    for x in range(5):
        self.canvas.widget().add_subplot()
        self.canvas.widget().adjustSize()

撰写回答