QScrollArea.ensureWidgetVisible方法不显示目标小部件

时间:2018-09-21 19:44:29

标签: python pyqt pyqt5 qscrollarea

我正在尝试使用方法QPushButton使最后一个QScrollArea().ensureWidgetVisible()可见,但是如您所见,该方法不会滚动到最后一个QPushButton

示例

能否请您帮助并解决我的问题,或者是 setFrameStyle 问题?预先谢谢你。

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class Widget(QWidget):

    def __init__(self, parent= None):
        super(Widget, self).__init__()
        self.setFixedHeight(200)

        #Container Widget        
        widget = QWidget()
        #Layout of Container Widget
        layout = QVBoxLayout(self)
        for _ in range(20):
            btn = QPushButton("test")
            layout.addWidget(btn)
        widget.setLayout(layout)


        #Scroll Area Properties
        scroll = QScrollArea()
        scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll.setWidgetResizable(False)
        scroll.setWidget(widget)

        # print(scroll.verticalScrollBar().maximum())
        # vbar = scroll.verticalScrollBar()
        # vbar.setValue(vbar.maximum())
        #vbar.setValue(vbar.maximum())


        #Scroll Area Layer add 
        vLayout = QVBoxLayout(self)
        vLayout.addWidget(scroll)
        self.setLayout(vLayout)


        # items = (layout.itemAt(i) for i in range(layout.count())) 
        # for w in items:
        #     print(w)
        print(layout.count())
        #scroll.ensureWidgetVisible(layout.itemAt(layout.count()-5).widget(), xMargin=10, yMargin=10 )
        scroll.ensureWidgetVisible(layout.itemAt(layout.count()-1).widget() )
        print(layout.itemAt(layout.count()-1).widget(),"last widget")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog = Widget()
    dialog.show()

    app.exec_()

1 个答案:

答案 0 :(得分:1)

问题是,出于效率原因,直到显示小部件尺寸时才进行计算或更新,在您的情况下,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)