在 PyQt5 上将滚动条设置到底部(使用 scrollArea 和 gridLayout)
Setting the scroll bar to the bottom on PyQt5 (using scrollArea and a gridLayout)
我有一个带有 QGridLayout 的 QScrollArea。这表示 QGridLayout 在 100x100 网格上充满了按钮。我希望垂直滚动条从底部而不是顶部开始。我在网上搜索了如何操作,但到目前为止没有任何效果。
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)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())
编辑:试图更好地解释 - 我需要滚动到底部,所以当我打开 window 时,滚动条在底部而不是在顶.
我尝试过的:
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setValue(x)
和
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setSliderPosition(x)
问题是滚动条几何图形在以下时间更新:
- 小部件设置为 QScrollArea。
- QScrollArea 可见。
- QScrollArea 的大小发生变化。
- 如果小部件可见,它的大小会发生变化。
所以先放widget再放按钮的时候,QScrollArea是不会被通知的,所以有2种解决方法:
显示后立即移动滚动条。
for i in range(100):
for j in range(100):
self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j)
QtCore.QTimer.singleShot(0, self.handle_timeout)
def handle_timeout(self):
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setValue(x)
放置按钮后将小部件设置为 QScrollArea。
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.layout.addWidget(self.scrollArea)
for i in range(100):
for j in range(100):
self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setValue(x)
虽然这个问题已经有了答案,但是,我遇到了一些类似的问题,即使尝试了@eyllanesc 的解决方案也没有解决。
所以,我正在分享对我有用的东西。
我从另一个 post、quick-link 那里得到了解决方案,尽管他的解决方案针对的主题有所不同。
解决方案:
# inside __init__ method
self.scrollArea.verticalScrollBar().rangeChanged.connect(
self.scrollToBottom,
)
# new function in same class
def scrollToBottom (self, minVal=None, maxVal=None):
# Additional params 'minVal' and 'maxVal' are declared because
# rangeChanged signal sends them, but we set it to optional
# because we may need to call it separately (if you need).
self.scrollArea.verticalScrollBar().setValue(
self.scrollArea.verticalScrollBar().maximum()
)
我有一个带有 QGridLayout 的 QScrollArea。这表示 QGridLayout 在 100x100 网格上充满了按钮。我希望垂直滚动条从底部而不是顶部开始。我在网上搜索了如何操作,但到目前为止没有任何效果。
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)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = IndicSelectWindow()
w.show()
sys.exit(app.exec_())
编辑:试图更好地解释 - 我需要滚动到底部,所以当我打开 window 时,滚动条在底部而不是在顶.
我尝试过的:
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setValue(x)
和
x = self.scrollArea.verticalScrollBar().maximum()
self.scrollArea.verticalScrollBar().setSliderPosition(x)
问题是滚动条几何图形在以下时间更新:
- 小部件设置为 QScrollArea。
- QScrollArea 可见。
- QScrollArea 的大小发生变化。
- 如果小部件可见,它的大小会发生变化。
所以先放widget再放按钮的时候,QScrollArea是不会被通知的,所以有2种解决方法:
显示后立即移动滚动条。
for i in range(100): for j in range(100): self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j) QtCore.QTimer.singleShot(0, self.handle_timeout) def handle_timeout(self): x = self.scrollArea.verticalScrollBar().maximum() self.scrollArea.verticalScrollBar().setValue(x)
放置按钮后将小部件设置为 QScrollArea。
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.layout.addWidget(self.scrollArea) for i in range(100): for j in range(100): self.gridLayout.addWidget(QtWidgets.QPushButton(), i, j) self.scrollArea.setWidget(self.scrollAreaWidgetContents) x = self.scrollArea.verticalScrollBar().maximum() self.scrollArea.verticalScrollBar().setValue(x)
虽然这个问题已经有了答案,但是,我遇到了一些类似的问题,即使尝试了@eyllanesc 的解决方案也没有解决。
所以,我正在分享对我有用的东西。
我从另一个 post、quick-link 那里得到了解决方案,尽管他的解决方案针对的主题有所不同。
解决方案:
# inside __init__ method
self.scrollArea.verticalScrollBar().rangeChanged.connect(
self.scrollToBottom,
)
# new function in same class
def scrollToBottom (self, minVal=None, maxVal=None):
# Additional params 'minVal' and 'maxVal' are declared because
# rangeChanged signal sends them, but we set it to optional
# because we may need to call it separately (if you need).
self.scrollArea.verticalScrollBar().setValue(
self.scrollArea.verticalScrollBar().maximum()
)