You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QWidget添加滚动条失效且绘图被压缩的问题求助

问题解决:QWidget中滚动视图失效与绘图压缩问题

核心问题分析

  • 绘图被压缩:Matplotlib画布(MplCanvas)的尺寸策略未正确配置,导致布局强制压缩其显示大小
  • 滚动条不工作:重复添加绘图部件导致布局内容混乱,且画布未保留足够高度触发滚动逻辑

修复步骤及代码修改

1. 修复MplCanvas的尺寸策略

取消注释尺寸策略设置,并调整为Preferred,确保画布保持预设宽高,避免被压缩:

canvas.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)

同时建议在MplCanvas类中明确设置最小尺寸,确保布局不会过度压缩:

class MplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=5, dpi=300, ...):
        super().__init__(Figure(figsize=(width, height), dpi=dpi))
        self.setParent(parent)
        # 强制设置最小尺寸
        self.setMinimumSize(self.figure.get_figwidth()*self.figure.dpi, 
                            self.figure.get_figheight()*self.figure.dpi)

2. 清空旧绘图,避免重复添加

在init_plot方法开头移除已有绘图部件(保留标题),防止重复添加导致布局溢出:

def init_plot(self):
    # 移除标题之外的所有旧部件
    while self.vbox.count() > 1:
        item = self.vbox.takeAt(1)
        widget = item.widget()
        if widget:
            widget.deleteLater()
    
    # 原有绘图逻辑
    for energy, label in zip(self.IRC_File[0, :].reshape(1, -1), self.Param_File[0, 1]):
        for i, (param, lab) in enumerate(zip(self.IRC_File[1:, :], self.Param_File[1:,0])):
            canvas = MplCanvas(self, width=5, height=5, dpi=300, x=param, y=energy, x_label=lab, y_label=label)
            canvas.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
            self.vbox.addWidget(canvas)

3. 优化滚动区域配置

确保滚动区域占满父布局空间,添加尺寸策略设置:

self.scrolls.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

修改后的完整代码

class PlottingPage(QtWidgets.QWidget):
    def __init__(self, parent=None, data=None):
        super().__init__(parent)
        self.parent = parent
        self.data = data

        self.scrolls = QtWidgets.QScrollArea()
        self.scrolls.setWidgetResizable(True)
        # 设置滚动区域尺寸策略,占满可用空间
        self.scrolls.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

        self.widget = QtWidgets.QWidget()
        self.vbox = QtWidgets.QVBoxLayout(self.widget)
        self.scrolls.setWidget(self.widget)

        self.title = QtWidgets.QLabel("Plots", alignment=QtCore.Qt.AlignTop)
        self.vbox.addWidget(self.title)

        main_layout = QtWidgets.QVBoxLayout(self)
        main_layout.addWidget(self.scrolls)

        if self.data:
            self.IRC_File = data[0]
            self.Param_File = data[1]


    def init_plot(self):
        # 清空旧绘图部件
        while self.vbox.count() > 1:
            item = self.vbox.takeAt(1)
            widget = item.widget()
            if widget:
                widget.deleteLater()
        
        for energy, label in zip(self.IRC_File[0, :].reshape(1, -1), self.Param_File[0, 1]):
            for i, (param, lab) in enumerate(zip(self.IRC_File[1:, :], self.Param_File[1:,0])):
                canvas = MplCanvas(self, width=5, height=5, dpi=300, x=param, y=energy, x_label=lab, y_label=label)
                canvas.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
                self.vbox.addWidget(canvas)

    def update_data(self, data):
        self.IRC_File = data[0]
        self.Param_File = data[1]
        self.init_plot()

额外说明

  • 如果MplCanvas的sizeHint()未正确返回预设尺寸,可手动重写该方法:
    def sizeHint(self):
        return QtCore.QSize(self.figure.get_figwidth()*self.figure.dpi, 
                            self.figure.get_figheight()*self.figure.dpi)
    
  • 滚动条仅在内容总高度超过滚动区域高度时显示,确保绘图数量或单图高度足够触发滚动。

内容的提问来源于stack exchange,提问作者Hamza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:31:19