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

如何在PySide2固定尺寸控件间实现动态间距调整

Fixing Widget Sizes & Auto-Adjusting Spacing on Window Resize in PySide2

Got it, let's work through this problem together! The core issue with your current code is that manual move() and resize() positioning doesn't handle window resizing dynamically—Qt's layout managers are built exactly for this kind of spacing adjustment, and QSizePolicy works alongside them to keep widgets fixed-size while letting gaps expand or shrink automatically.

Why Your Current Setup Isn't Working

Manual positioning ties widgets to absolute coordinates, so when the window resizes, those coordinates don't update. QSizePolicy can't help here because it only controls how layouts interact with widget sizing—without a layout, it has no framework to work with.

The Solution: Layout Managers + Fixed-Size Policies

We’ll rewrite your code to use Qt’s layout system, lock in widget sizes, and add flexible "stretch" spaces that grow/shrink when the window resizes. Here’s the modified version:

from PySide2 import QtWidgets
from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout
from PySide2.QtGui import QPainter, QBrush, QColor
from PySide2.QtCore import Qt
import sys

class LeftPanel(QWidget):
    def paintEvent(self, e):
        qp = QPainter(self)
        qp.setPen(QColor('#d4d4d4'))
        qp.setBrush(QColor(200, 50, 8))
        qp.drawRect(self.rect())  # Draw to match widget's auto-sized height

class CenterPanel(QWidget):
    def paintEvent(self, e):
        qp = QPainter(self)
        qp.setPen(QColor('#d4d4d4'))
        qp.setBrush(QColor(250, 255, 250))
        qp.drawRect(self.rect())

class MyWindow(QMainWindow):
    def __init__(self):
        super(MyWindow,self).__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(200, 200, 300, 300)
        self.setWindowTitle("test app")

        # QMainWindow needs a central widget to hold layouts
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Main horizontal layout splits window into left panel + right content
        main_layout = QHBoxLayout(central_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)  # Remove default window margins
        main_layout.setSpacing(10)  # Fixed gap between left and right sections

        # Left fixed-width panel
        left_panel = LeftPanel()
        left_panel.setFixedWidth(100)  # Width stays fixed, height matches window
        main_layout.addWidget(left_panel)

        # Right content container (fixed width to match your original widget sizes)
        right_container = QWidget()
        right_container.setFixedWidth(180)
        right_layout = QVBoxLayout(right_container)
        right_layout.setSpacing(0)  # We'll use stretches for dynamic spacing

        # Add input field with fixed size
        self.label = QtWidgets.QLineEdit()
        self.label.setText("my first label!")
        self.label.setFixedSize(180, 25)
        # Lock size policy to ensure layout doesn't resize it
        self.label.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        right_layout.addWidget(self.label)

        # Add flexible stretch: expands when window grows to push widgets apart
        right_layout.addStretch()

        # Add center panel with fixed size
        center_panel = CenterPanel()
        center_panel.setFixedSize(180, 180)
        center_panel.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        right_layout.addWidget(center_panel)

        # Another stretch between center panel and button
        right_layout.addStretch()

        # Add button aligned to the right
        button_layout = QHBoxLayout()
        button_layout.addStretch()  # Push button to the right side
        self.b1 = QtWidgets.QPushButton()
        self.b1.setText("Fixed Button size!")
        self.b1.setFixedSize(110, 25)
        self.b1.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        self.b1.setStyleSheet("""
            background-color: #4CAF50;
            border: none;
            color: white;
            text-align: center;
            font-size: 12px;
            font-family: Arial
        """)
        button_layout.addWidget(self.b1)
        right_layout.addLayout(button_layout)

        # Add right container to main layout
        main_layout.addWidget(right_container)

def window():
    app = QApplication(sys.argv)
    win = MyWindow()
    win.show()
    sys.exit(app.exec_())

window()

Key Changes Breakdown

  1. Central Widget: QMainWindow requires a central widget to hold layouts—you can’t apply layouts directly to the main window itself.
  2. Layout Structure:
    • A main QHBoxLayout splits the window into left and right sections.
    • The right section uses a QVBoxLayout to stack widgets vertically.
  3. Fixed Sizes: Every widget and panel has a fixed size, and QSizePolicy.Fixed ensures layouts won’t stretch or shrink them.
  4. Stretches: addStretch() adds flexible blank space between widgets. When the window resizes, these stretches expand or contract, creating dynamic spacing while keeping widgets fixed-size.
  5. Aligned Button: A nested QHBoxLayout with a stretch keeps the button aligned to the right, matching your original placement.

Now when you resize the window:

  • All widgets stay their fixed size.
  • Vertical resizing makes the gaps between the input field, center panel, and button grow/shrink.
  • Horizontal resizing keeps the left panel at 100px and right container at 180px, with a fixed 10px gap between them.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:53:10