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

PyQt6中嵌入pyqtgraph的GraphicsLayoutWidget时QScrollArea滚动条不显示

问题:PyQt6中QScrollArea嵌入pyqtgraph GraphicsLayoutWidget后滚动条不显示

尝试在PyQt6的QScrollArea中嵌入pyqtgraph的GraphicsLayoutWidget,让滚动条正常显示。试过修改布局、重新分配GraphicsLayoutWidget、设置默认最小尺寸和调用show()函数,问题仍未解决。

问题核心代码

def update_graphs(self):
    self.graphWidget.clear()
    self.graph_data = pd.concat([self.data[(self.data['time'] > (comment - self.time_before)) & (self.data['time'] < (comment + self.time_after))] for comment in self.selected_comments['time']])
    self.graph_dict = dict.fromkeys(self.graph_data.columns.values[:-1], None)
    time = (self.graph_data['time'].dt.tz_localize(None) - pd.Timestamp("1970-01-01") + pd.Timedelta('5h')) / pd.Timedelta('1s')
    for i, trace in enumerate(self.graph_dict.keys()):
        self.graph_dict[trace] = self.graphWidget.addPlot(row=i,
                                                          col=0,
                                                          name=trace,
                                                          title=trace
                                                          )
        self.graph_dict[trace].setMinimumHeight(150)
        self.graph_dict[trace].addItem(pg.PlotCurveItem(clear=True,
                                                        pen='g',
                                                        x=time.values,
                                                        y=self.graph_data[trace].values),
                                       row=i,
                                       col=0)
        self.graph_dict[trace].setXLink(list(self.graph_dict.keys())[0])
        y_axis = pg.AxisItem(orientation='left', text='Voltage', units='V', unitPrefix='m')
        y_axis.setLabel(text='Voltage', units='V')
        y_axis.setScale(1e-3)
        self.graph_dict[trace].setAxisItems({'bottom': pg.DateAxisItem(orientation='bottom'),
                                             'left': y_axis})
        if not i == len(self.graph_dict) - 1:
            self.graph_dict[trace].hideAxis('bottom')
    self.scrollArea.show()

Qt Designer生成的相关代码

self.scrollArea = QtWidgets.QScrollArea(parent=self.graphTab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
self.scrollArea.setSizePolicy(sizePolicy)
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.scrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustIgnored)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.graphWidget = GraphicsLayoutWidget()
self.graphWidget.setGeometry(QtCore.QRect(0, 0, 1043, 655))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graphWidget.sizePolicy().hasHeightForWidth())
self.graphWidget.setSizePolicy(sizePolicy)
self.graphWidget.setObjectName("graphWidget")
self.scrollArea.setWidget(self.graphWidget)

解决方案

关键问题分析

QScrollArea显示滚动条的前提是内部widget的尺寸超过了scrollArea的可视区域,当前代码存在两个核心问题:

  1. GraphicsLayoutWidget被设置了固定初始尺寸,添加多个Plot后无法自动更新自身总尺寸以容纳所有内容;
  2. 仅给单个Plot设置最小高度,但未同步更新GraphicsLayoutWidget的整体最小尺寸,导致scrollArea无法感知内容溢出。

修复步骤

  1. 移除固定初始尺寸:删掉self.graphWidget.setGeometry(QtCore.QRect(0, 0, 1043, 655)),让GraphicsLayoutWidget根据内容自动计算尺寸;
  2. 调整scrollArea的尺寸适配策略:将SizeAdjustPolicy从AdjustIgnored改为AdjustToContents,确保scrollArea能根据内部widget尺寸调整滚动逻辑;
  3. 强制更新GraphicsLayoutWidget的最小高度:添加完所有Plot后,根据Plot数量计算总最小高度并设置,触发scrollArea的滚动条逻辑。

修改后的代码

调整Qt Designer生成的代码

self.scrollArea = QtWidgets.QScrollArea(parent=self.graphTab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
self.scrollArea.setSizePolicy(sizePolicy)
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarPolicy.ScrollBarAsNeeded)
# 修改尺寸适配策略
self.scrollArea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.graphWidget = GraphicsLayoutWidget()
# 移除固定尺寸设置
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.graphWidget.sizePolicy().hasHeightForWidth())
self.graphWidget.setSizePolicy(sizePolicy)
self.graphWidget.setObjectName("graphWidget")
self.scrollArea.setWidget(self.graphWidget)

修改update_graphs方法

在方法末尾添加尺寸更新逻辑:

def update_graphs(self):
    self.graphWidget.clear()
    self.graph_data = pd.concat([self.data[(self.data['time'] > (comment - self.time_before)) & (self.data['time'] < (comment + self.time_after))] for comment in self.selected_comments['time']])
    self.graph_dict = dict.fromkeys(self.graph_data.columns.values[:-1], None)
    time = (self.graph_data['time'].dt.tz_localize(None) - pd.Timestamp("1970-01-01") + pd.Timedelta('5h')) / pd.Timedelta('1s')
    plot_count = len(self.graph_dict.keys())
    for i, trace in enumerate(self.graph_dict.keys()):
        self.graph_dict[trace] = self.graphWidget.addPlot(row=i,
                                                          col=0,
                                                          name=trace,
                                                          title=trace
                                                          )
        self.graph_dict[trace].setMinimumHeight(150)
        self.graph_dict[trace].addItem(pg.PlotCurveItem(clear=True,
                                                        pen='g',
                                                        x=time.values,
                                                        y=self.graph_data[trace].values),
                                       row=i,
                                       col=0)
        self.graph_dict[trace].setXLink(list(self.graph_dict.keys())[0])
        y_axis = pg.AxisItem(orientation='left', text='Voltage', units='V', unitPrefix='m')
        y_axis.setLabel(text='Voltage', units='V')
        y_axis.setScale(1e-3)
        self.graph_dict[trace].setAxisItems({'bottom': pg.DateAxisItem(orientation='bottom'),
                                             'left': y_axis})
        if not i == plot_count - 1:
            self.graph_dict[trace].hideAxis('bottom')
    # 计算并设置graphWidget的总最小高度
    total_min_height = plot_count * 150
    self.graphWidget.setMinimumHeight(total_min_height)
    # 强制更新布局,确保尺寸生效
    self.graphWidget.updateGeometry()
    self.scrollArea.show()

额外说明

  • 保持setWidgetResizable(True)不变,该属性让scrollArea自动适配内部widget的宽度,仅在高度方向触发滚动;
  • 若需要更精确的尺寸计算,可通过获取每个Plot的实际高度求和,替代固定的150*plot_count。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:02:20