PyQt5中scrollArea嵌套gridLayout时如何设置垂直滚动条默认位于底部
问题原因
你尝试的两个方法失效的核心原因是:在__init__方法执行阶段,QScrollArea 内部的网格布局和所有按钮还未完成实际的渲染与尺寸计算,此时垂直滚动条的maximum属性仍然是默认值0,赋值操作自然不会生效。
可行解决方案
这里提供两种经过验证的实现方式:
方案1:单次定时器延迟执行
利用QTimer.singleShot将滚动条赋值操作放到事件循环空闲阶段执行,此时控件已经完成所有初始化计算:
import sys from PyQt5 import QtWidgets, QtCore class IndicSelectWindow(QtWidgets.QDialog): def __init__(self, parent=None): super(IndicSelectWindow, self).__init__(parent=parent) self.resize(500, 400) self.layout = QtWidgets.QHBoxLayout(self) self.scrollArea = QtWidgets.QScrollArea(self) self.scrollArea.setWidgetResizable(True) self.scrollAreaWidgetContents = QtWidgets.QWidget() self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.layout.addWidget(self.scrollArea) for i in range(100): for j in range(100): self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j) # 延迟执行滚动操作 QtCore.QTimer.singleShot(0, self.scroll_to_bottom) def scroll_to_bottom(self): v_bar = self.scrollArea.verticalScrollBar() v_bar.setValue(v_bar.maximum()) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) w = IndicSelectWindow() w.show() sys.exit(app.exec_())
方案2:重写showEvent方法
如果需要确保窗口每次显示时都触发滚动(或者仅首次显示滚动),可以重写窗口的showEvent回调,该回调会在窗口实际显示到屏幕后触发:
import sys from PyQt5 import QtWidgets class IndicSelectWindow(QtWidgets.QDialog): def __init__(self, parent=None): super(IndicSelectWindow, self).__init__(parent=parent) self.resize(500, 400) self.layout = QtWidgets.QHBoxLayout(self) self.scrollArea = QtWidgets.QScrollArea(self) self.scrollArea.setWidgetResizable(True) self.scrollAreaWidgetContents = QtWidgets.QWidget() self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents) self.scrollArea.setWidget(self.scrollAreaWidgetContents) self.layout.addWidget(self.scrollArea) for i in range(100): for j in range(100): self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j) def showEvent(self, event): super().showEvent(event) # 加标记保证仅首次显示时滚动到底部,不需要可以去掉判断 if not hasattr(self, '_is_first_show'): self._is_first_show = True v_bar = self.scrollArea.verticalScrollBar() v_bar.setValue(v_bar.maximum()) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) w = IndicSelectWindow() w.show() sys.exit(app.exec_())
两种方案都可以实现窗口打开时垂直滚动条默认处于最底部的需求,可根据实际业务场景选择。
内容的提问来源于stack exchange,提问作者Gabriel Martinez
相关产品推荐
相关产品推荐

