如何在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
- Central Widget: QMainWindow requires a central widget to hold layouts—you can’t apply layouts directly to the main window itself.
- Layout Structure:
- A main
QHBoxLayoutsplits the window into left and right sections. - The right section uses a
QVBoxLayoutto stack widgets vertically.
- A main
- Fixed Sizes: Every widget and panel has a fixed size, and
QSizePolicy.Fixedensures layouts won’t stretch or shrink them. - 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. - Aligned Button: A nested
QHBoxLayoutwith 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

