You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为PyQt5主窗口添加滚动条?尝试方案未生效求指导

PyQt5主窗口添加滚动条的正确实现

你尝试为PyQt5主窗口添加滚动条但未成功,以下是问题分析和解决方案:

初始代码

from PyQt5.QtWidgets import *
import sys

class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Python ")
        self.setGeometry(100, 100, 600, 400)
        self.UiComponents()
        self.show()

    def UiComponents(self):
        emphysemaLabel = QLabel("EMPHYSEMA", self)
        emphysemaLabel.move(10, 10)

        ggoLabel = QLabel("GGO", self)
        ggoLabel.move(10, 300)

        condensLabel = QLabel("Condens", self)
        condensLabel.move(10, 590)

        emphysema_graph_lin = QLabel(self)
        emphysema_graph_lin.resize(302, 232)
        emphysema_graph_lin.move(10, 50)
        emphysema_graph_lin.setStyleSheet("background-color:yellow;")

        ggo_graph_lin = QLabel(self)
        ggo_graph_lin.resize(302, 232)
        ggo_graph_lin.move(10, 340)
        ggo_graph_lin.setStyleSheet("background-color:yellow;")

        condens_graph_lin = QLabel(self)
        condens_graph_lin.resize(302, 232)
        condens_graph_lin.move(10, 630)
        condens_graph_lin.setStyleSheet("background-color:yellow;")

if __name__ == "__main__": 
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec())

修改后未生效的代码

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


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Python ")
        self.setGeometry(100, 100, 600, 400)
        self.UiComponents()
        self.show()

    def UiComponents(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

        emphysemaLabel = QLabel("EMPHYSEMA", self)
        emphysemaLabel.move(10, 10)
        self.vbox.addWidget(emphysemaLabel)

        ggoLabel = QLabel("GGO", self)
        ggoLabel.move(10, 300)
        self.vbox.addWidget(ggoLabel)

        condensLabel = QLabel("Condens", self)
        condensLabel.move(10, 590)
        self.vbox.addWidget(condensLabel)

        emphysema_graph_lin = QLabel(self)
        emphysema_graph_lin.resize(302, 232)
        emphysema_graph_lin.move(10, 50)
        emphysema_graph_lin.setStyleSheet("background-color:yellow;")
        self.vbox.addWidget(emphysema_graph_lin)

        ggo_graph_lin = QLabel(self)
        ggo_graph_lin.resize(302, 232)
        ggo_graph_lin.move(10, 340)
        ggo_graph_lin.setStyleSheet("background-color:yellow;")
        self.vbox.addWidget(ggo_graph_lin)

        condens_graph_lin = QLabel(self)
        condens_graph_lin.resize(302, 232)
        condens_graph_lin.move(10, 630)
        condens_graph_lin.setStyleSheet("background-color:yellow;")
        self.vbox.addWidget(condens_graph_lin)

        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)


if __name__ == "__main__":
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec())

错误原因

  1. 所有控件的父类被设为self(主窗口),但实际上它们应该属于滚动区域内的self.widget,否则布局无法正确管理这些控件。
  2. 使用了move()和resize()手动定位控件,而布局会忽略这些手动设置,自行管理控件的位置和大小,导致控件排列混乱,滚动区域无法正确计算内容高度。

正确实现代码

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


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Python ")
        self.setGeometry(100, 100, 600, 400)
        self.UiComponents()
        self.show()

    def UiComponents(self):
        # 创建滚动区域并设为中心部件
        scroll_area = QScrollArea()
        scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scroll_area.setWidgetResizable(True)

        # 创建滚动区域的内容容器
        content_widget = QWidget()
        scroll_area.setWidget(content_widget)

        # 创建垂直布局,用于排列控件
        layout = QVBoxLayout(content_widget)
        # 设置布局间距,模拟原代码的位置间隔
        layout.setSpacing(20)
        layout.setContentsMargins(10, 10, 10, 10)

        # 添加标题标签
        emphysema_label = QLabel("EMPHYSEMA")
        layout.addWidget(emphysema_label)

        # 添加第一个图表标签,设置固定大小
        emphysema_graph = QLabel()
        emphysema_graph.setFixedSize(302, 232)
        emphysema_graph.setStyleSheet("background-color:yellow;")
        layout.addWidget(emphysema_graph)

        # 添加第二个标题标签
        ggo_label = QLabel("GGO")
        layout.addWidget(ggo_label)

        # 添加第二个图表标签
        ggo_graph = QLabel()
        ggo_graph.setFixedSize(302, 232)
        ggo_graph.setStyleSheet("background-color:yellow;")
        layout.addWidget(ggo_graph)

        # 添加第三个标题标签
        condens_label = QLabel("Condens")
        layout.addWidget(condens_label)

        # 添加第三个图表标签
        condens_graph = QLabel()
        condens_graph.setFixedSize(302, 232)
        condens_graph.setStyleSheet("background-color:yellow;")
        layout.addWidget(condens_graph)

        # 将滚动区域设为主窗口的中心部件
        self.setCentralWidget(scroll_area)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    sys.exit(app.exec())

关键要点

  • 所有控件的父类默认会被布局设置为content_widget,不需要手动指定。
  • 使用setFixedSize()来保证图表控件的尺寸,替代手动resize()。
  • 通过布局的setSpacing()和setContentsMargins()来控制控件之间的间距,替代手动move()。
  • 滚动区域的setWidgetResizable(True)会让内容容器自动适应滚动区域的宽度,同时保持内容高度以显示滚动条。

内容的提问来源于stack exchange,提问作者bags

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:56:55