Show several plots in a scrollable widget with PyQt and matplotlib

蹲街弑〆低调 提交于 2019-12-05 08:03:21

问题


Since I didn't get an answer for this question I tried solving it with PyQt. Apparently, it's not that easy, when QScrollArea is involved...

I wrote a small test that basically does what I'm looking for, but it's not showing the scroll area and the plots inside it as I expected:

from PyQt4 import QtCore, QtGui
import os,sys

#import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure

qapp = QtGui.QApplication(sys.argv)
qwidget = QtGui.QWidget()
qwidget.setGeometry(QtCore.QRect(0, 0, 500, 500))
qlayout = QtGui.QHBoxLayout(qwidget)
qwidget.setLayout(qlayout)

qscroll = QtGui.QScrollArea(qwidget)
qscroll.setGeometry(QtCore.QRect(0, 0, 500, 500))
qscroll.setFrameStyle(QtGui.QFrame.NoFrame)
qlayout.addWidget(qscroll)

qscrollContents = QtGui.QWidget()
qscrollLayout = QtGui.QVBoxLayout(qscrollContents)
qscrollLayout.setGeometry(QtCore.QRect(0, 0, 1000, 1000))

qscroll.setWidget(qscrollContents)
qscroll.setWidgetResizable(True)

for i in xrange(5):
  qfigWidget = QtGui.QWidget(qscrollContents)
  fig = Figure((5.0, 4.0), dpi=100)
  canvas = FigureCanvas(fig)
  canvas.setParent(qfigWidget)
  toolbar = NavigationToolbar(canvas, qfigWidget)
  axes = fig.add_subplot(111)
  axes.plot([1,2,3,4])
  qscrollLayout.addWidget(qfigWidget)

qscrollContents.setLayout(qscrollLayout)

qwidget.show()
exit(qapp.exec_()) 

Can anyone explain why it's not working?


回答1:


You are creating a QWidget for each plot. But you don't put your canvas or toolbar in it via a layout, so they can't communicate the size information with the QWidget. By default, a QWidget has no minimumSize and the widget/layout inside the QScrollArea can make them as small as it wants in order to fit the available space (which is the size of QScrollArea).

Adding plots via layout helps, but I find that the FigureCanvas widget also doesn't have any minimum size so it can shrink. For a quick fix, you can set a minimumSize. The loop part with these fixes should look like this:

for i in xrange(5):
  qfigWidget = QtGui.QWidget(qscrollContents)

  fig = Figure((5.0, 4.0), dpi=100)
  canvas = FigureCanvas(fig)
  canvas.setParent(qfigWidget)
  toolbar = NavigationToolbar(canvas, qfigWidget)
  axes = fig.add_subplot(111)
  axes.plot([1,2,3,4])

  # place plot components in a layout
  plotLayout = QtGui.QVBoxLayout()
  plotLayout.addWidget(canvas)
  plotLayout.addWidget(toolbar)
  qfigWidget.setLayout(plotLayout)

  # prevent the canvas to shrink beyond a point
  # original size looks like a good minimum size
  canvas.setMinimumSize(canvas.size())

  qscrollLayout.addWidget(qfigWidget)


来源:https://stackoverflow.com/questions/12234917/show-several-plots-in-a-scrollable-widget-with-pyqt-and-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!