PyQt:如何创建可滚动窗口

10

我认为在PyQt中创建可滚动窗口应该会更容易些。我有一个标签列表,它超出了窗口,并且我想向下滚动以查看它们。目前,代码没有给我任何错误提示,但窗口却没有显示出来:

class Example(QWidget):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()

        lbl_arr = makeLabelArr()

        for i in range(1,8):
            qb = lbl_arr[i]
            # qb.setFixedWidth(300)
            layout.addWidget(qb)

        layout.setAlignment(Qt.AlignTop)

        scroll = QScrollArea()
        scroll.setWidget(self)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(400)

        layout.addWidget(scroll)

        self.setLayout(layout)


        self.setGeometry(0, 0, 600, 220)
        self.setWindowTitle('SnP watchlist')

        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    #print(QDesktopWidget().availableGeometry())

    ex = Example()
    sys.exit(app.exec_())
4个回答

10
将窗口本身设置为 QScrollArea,如下所示:
class Window(QScrollArea):
    def __init__(self):
        super(Window, self).__init__()
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setAlignment(Qt.AlignTop)
        for index in range(100):
            layout.addWidget(QLabel('Label %02d' % index))
        self.setWidget(widget)
        self.setWidgetResizable(True)

我尝试过不使用布局,但是它没有起作用。我没有继承“QMainWindow”类,而是创建了一个“QWidget”对象,并在我想要制作的每个“Q”项中传递了该对象。例如:https://pastebin.com/ZDKNXZPZ。这是错误的方法吗?我已经创建了没有布局的窗口。 - Filip
@Filip 请提出新问题 - ekhumoro
做不到那个。还是谢谢你。 - Filip

3

这里有一个示例:https://www.learnpyqt.com/tutorials/qscrollarea/

from PyQt5.QtWidgets import (QWidget, QSlider, QLineEdit, QLabel, QPushButton, QScrollArea,QApplication,
                             QHBoxLayout, QVBoxLayout, QMainWindow)
from PyQt5.QtCore import Qt, QSize
from PyQt5 import QtWidgets, uic
import sys


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.scroll = QScrollArea()             # Scroll Area which contains the widgets, set as the centralWidget
        self.widget = QWidget()                 # Widget that contains the collection of Vertical Box
        self.vbox = QVBoxLayout()               # The Vertical Box that contains the Horizontal Boxes of  labels and buttons

        for i in range(1,50):
            object = QLabel("TextLabel: "+str(i))
            self.vbox.addWidget(object)

        self.widget.setLayout(self.vbox)

        #Scroll Area Properties
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scroll.setWidgetResizable(True)
        self.scroll.setWidget(self.widget)

        self.setCentralWidget(self.scroll)

        self.setGeometry(600, 100, 1000, 900)
        self.setWindowTitle('Scroll Area Demonstration')
        self.show()

        return

def main():
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

0

在添加滚动条小部件后,您应该设置布局

class Example(QWidget):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()

        lbl_arr = makeArrayOfLabelsHTML()

        for i in range(1,8):
            qb = lbl_arr[i]
            layout.addWidget(qb)

        layout.setAlignment(Qt.AlignTop)

        scroll = QScrollArea()
        scroll.setWidget(self)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(400)
        layout.addWidget(scroll)

        # set layout after adding scroll bar 
        self.setLayout(layout)

        self.setGeometry(0, 0, 600, 220)
        self.setWindowTitle('SnP watchlist')

        self.show()



if __name__ == '__main__':

        app = QApplication(sys.argv)
        #print(QDesktopWidget().availableGeometry())

        ex = Example()
        sys.exit(app.exec_())

1
谢谢您的回复,但是即使我没有收到错误提示,窗口仍然没有显示出来。 - user3755529

0
这说明了一种做事的方式
import sys 
from PyQt5 import QtWidgets, QtCore

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(600, 200)
        self.setWindowTitle('One way to do scrolling')
        
        def add_stuff():
            self.add_stuff()
        QtCore.QTimer.singleShot(500, add_stuff)

    def add_stuff(self):
        self.resize(1200, 800)
        
        # comment out these blocks, starting with the bottom one
        
        central_widget = QtWidgets.QFrame(self)
        self.setCentralWidget(central_widget)
        central_widget.setLayout(QtWidgets.QVBoxLayout(central_widget))
        central_widget.setStyleSheet('border: 5px solid green;')
        
        scroll_area = QtWidgets.QScrollArea()
        scroll_area.setWidgetResizable(True)
        central_widget.layout().addWidget(scroll_area)
        scroll_area.setStyleSheet('border: 5px solid blue;')
        
        main_panel = QtWidgets.QFrame(central_widget)
        main_panel.setStyleSheet('border: 5px solid red;')
        scroll_area.setWidget(main_panel)
        
        # the crucial line: without this, main_panel will just adapt
        # its size to its parent by default
        main_panel.setMinimumSize(600, 500)
        
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()        

运行此代码,然后使用鼠标缩小窗口。

还要注意,一些组件(如QTableViewQTreeView)会自动实现滚动功能。

最重要的是要理解,滚动发生是因为子组件变得太大而超出了父组件的范围(并且父组件已经设置了滚动)。setMinimumSize是一种非常明显的方式来说明这个约束:通常情况下,启用滚动的父组件的子组件将包含某些子组件,这些子组件在某个点上将具有无法压缩的大小...子组件的配置layout对象也会影响确定子组件的最小尺寸。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接