如何实现自己的 QScrollArea
How to implement an own QScrollArea
我正在尝试理解QScrollArea is working to implement my own MyQScrollArea
widget. MyQScrollArea
should make use of setViewportMargins的方式。为此,我写了一个最小的工作示例,如下所示:
from PyQt5 import QtWidgets
import sys
class MyScrollArea(QtWidgets.QAbstractScrollArea):
def __init__(self):
super().__init__()
self.label = QtWidgets.QLabel(", ".join(map(str, range(100))), self)
hScrollBar = self.horizontalScrollBar()
hScrollBar.setRange(0, self.label.sizeHint().width() - self.sizeHint().width())
hScrollBar.valueChanged.connect(self._HScrollBarValueChanged)
self.setViewportMargins(100, 0, 0, 0)
self._HScrollBarValueChanged(0)
def _HScrollBarValueChanged(self, value):
self.label.move(-value + self.viewportMargins().left(), 0)
def main():
app = QtWidgets.QApplication(sys.argv)
scroll = MyScrollArea()
scroll.show()
app.exec_()
if __name__ == "__main__":
main()
代码结果如下图:
但是,在我滚动之后,内部小部件移出视口并在我不希望它被绘制的区域中绘制自身:
我哪里做错了,我怎样才能使 setViewportMargins 功能正常工作?
除了每次修改小部件的几何形状时修改 QScrollBar 的属性外,您还必须将 QLabel 设置为视口的子项:
import sys
from PyQt5 import QtWidgets
class MyScrollArea(QtWidgets.QAbstractScrollArea):
def __init__(self):
super().__init__()
self.label = QtWidgets.QLabel(", ".join(map(str, range(100))), self.viewport())
self.setViewportMargins(100, 0, 0, 0)
self.horizontalScrollBar().valueChanged.connect(
self.on_hscrollbar_value_changed
)
self.update_scrollbar()
def on_hscrollbar_value_changed(self, value):
self.label.move(-value, 0)
def update_scrollbar(self):
self.horizontalScrollBar().setRange(
0, self.label.sizeHint().width() - self.viewport().width()
)
self.horizontalScrollBar().setPageStep(self.viewport().width())
def resizeEvent(self, event):
self.update_scrollbar()
super().resizeEvent(event)
def main():
app = QtWidgets.QApplication(sys.argv)
scroll = MyScrollArea()
scroll.show()
app.exec_()
if __name__ == "__main__":
main()
我正在尝试理解QScrollArea is working to implement my own MyQScrollArea
widget. MyQScrollArea
should make use of setViewportMargins的方式。为此,我写了一个最小的工作示例,如下所示:
from PyQt5 import QtWidgets
import sys
class MyScrollArea(QtWidgets.QAbstractScrollArea):
def __init__(self):
super().__init__()
self.label = QtWidgets.QLabel(", ".join(map(str, range(100))), self)
hScrollBar = self.horizontalScrollBar()
hScrollBar.setRange(0, self.label.sizeHint().width() - self.sizeHint().width())
hScrollBar.valueChanged.connect(self._HScrollBarValueChanged)
self.setViewportMargins(100, 0, 0, 0)
self._HScrollBarValueChanged(0)
def _HScrollBarValueChanged(self, value):
self.label.move(-value + self.viewportMargins().left(), 0)
def main():
app = QtWidgets.QApplication(sys.argv)
scroll = MyScrollArea()
scroll.show()
app.exec_()
if __name__ == "__main__":
main()
代码结果如下图:
但是,在我滚动之后,内部小部件移出视口并在我不希望它被绘制的区域中绘制自身:
我哪里做错了,我怎样才能使 setViewportMargins 功能正常工作?
除了每次修改小部件的几何形状时修改 QScrollBar 的属性外,您还必须将 QLabel 设置为视口的子项:
import sys
from PyQt5 import QtWidgets
class MyScrollArea(QtWidgets.QAbstractScrollArea):
def __init__(self):
super().__init__()
self.label = QtWidgets.QLabel(", ".join(map(str, range(100))), self.viewport())
self.setViewportMargins(100, 0, 0, 0)
self.horizontalScrollBar().valueChanged.connect(
self.on_hscrollbar_value_changed
)
self.update_scrollbar()
def on_hscrollbar_value_changed(self, value):
self.label.move(-value, 0)
def update_scrollbar(self):
self.horizontalScrollBar().setRange(
0, self.label.sizeHint().width() - self.viewport().width()
)
self.horizontalScrollBar().setPageStep(self.viewport().width())
def resizeEvent(self, event):
self.update_scrollbar()
super().resizeEvent(event)
def main():
app = QtWidgets.QApplication(sys.argv)
scroll = MyScrollArea()
scroll.show()
app.exec_()
if __name__ == "__main__":
main()