【问题标题】:How to implement an own QScrollArea如何实现自己的 QScrollArea
【发布时间】:2020-04-23 07:00:25
【问题描述】:

我试图了解QScrollArea 是如何实现我自己的MyQScrollArea 小部件的。 MyQScrollArea 应该使用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 功能正常工作?

【问题讨论】:

    标签: python pyqt pyqt5 qscrollarea


    【解决方案1】:

    除了每次修改小部件的几何形状时修改 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()
    

    【讨论】:

    • 你不知道我尝试了多少东西,但我没有尝试将视口设置为父级。感谢您指出这一点。其余缺少的代码是由于最小的工作示例。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2017-09-08
    • 2017-01-16
    • 2017-02-22
    • 2016-05-02
    • 2012-02-12
    • 1970-01-01
    • 2013-05-13
    • 1970-01-01
    相关资源
    最近更新 更多