Проблема состоит в том, что из соображений эффективности размеры виджетов не рассчитываются и не обновляются до тех пор, пока они не отображаются, в вашем случае область просмотра QScrollArea
не обновила свой размер и поэтому перемещает прокрутку в промежуточное положение.Возможное решение - использовать QTimer::singleShot()
для вызова функции ensureWidgetVisible()
через мгновение после ее отображения:
import sys
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent= None):
super(Widget, self).__init__(parent)
self.setFixedHeight(200)
#Container Widget
widget =QtWidgets.QWidget()
#Layout of Container Widget
layout = QtWidgets.QVBoxLayout(widget)
for _ in range(20):
btn = QtWidgets.QPushButton("test")
layout.addWidget(btn)
scroll = QtWidgets.QScrollArea()
scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scroll.setWidgetResizable(False)
scroll.setWidget(widget)
#Scroll Area Layer add
vLayout = QtWidgets.QVBoxLayout(self)
vLayout.addWidget(scroll)
last_widget = layout.itemAt(layout.count()-1).widget()
QtCore.QTimer.singleShot(0, partial(scroll.ensureWidgetVisible, last_widget))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
dialog = Widget()
dialog.show()
sys.exit(app.exec_())
или просто вызвать show()
до:
...
last_widget = layout.itemAt(layout.count()-1).widget()
self.show()
scroll.ensureWidgetVisible(last_widget)