如何让含QScrollArea的QDialog自适应内容宽度显示3列单选按钮?
PyQt5 QScrollArea 自适应宽度显示3列单选按钮问题解决
问题根源
代码未启用QScrollArea的setWidgetResizable(True),导致内部QWidget无法根据滚动区域宽度自动调整布局,加上窗口默认宽度限制,3列单选按钮被截断为仅显示2列;同时水平滚动条被关闭,内容无法横向展开。
解决步骤
- 给QScrollArea添加
scroll.setWidgetResizable(True),让滚动区域自动调整内部widget宽度以匹配自身可用宽度,同时保留垂直滚动功能。 - 给内部QWidget的QGridLayout设置合理边距和间距,优化显示效果。
- 无需额外固定大小策略,QDialog会根据内容自适应宽度。
修改后的完整代码
#!/usr/bin/env python3 import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import * class LanguageDialog(QDialog): def __init__(self): super().__init__() # Language widget wdg_lang = self._language_widget() # Scroll area scroll = QScrollArea(self) scroll.setWidgetResizable(True) # 核心设置:启用内部widget自动适配宽度 scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll.setWidget(wdg_lang) # Button "Apply" button = QDialogButtonBox(QDialogButtonBox.Apply) button.clicked.connect(self.accept) # Dialog layout layout = QVBoxLayout(self) layout.addWidget(scroll) layout.addWidget(button) def _language_widget(self): """ nativ | ownlocal -> tooltip: english (code) """ grid = QGridLayout() grid.setContentsMargins(10, 10, 10, 10) # 设置布局边距 grid.setSpacing(8) # 设置控件间距 wdg = QWidget(self) wdg.setLayout(grid) for col in range(1, 4): for row in range(1, 24): r = QRadioButton(f'{col} x {row} | Lorem ipsum dolor sit amet', self) r.toggled.connect(self.slot_radio) r.mydata = (col, row) grid.addWidget(r, row, col) return wdg def slot_radio(self, val): btn = self.sender() if btn.isChecked(): print(f'{btn.mydata=}') class Window(QMainWindow): def __init__(self, parent=None): super().__init__(parent) def showEvent(self, e): dlg = LanguageDialog() dlg.exec() if __name__ == "__main__": app = QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec())
关键修改说明
scroll.setWidgetResizable(True):启用后,QScrollArea会强制内部widget的宽度匹配自身可用宽度,QGridLayout的3列单选按钮就能完全展开显示;内容高度超出窗口时,垂直滚动条会按需出现。- 布局边距与间距:
grid.setContentsMargins和grid.setSpacing用于优化控件显示的留白,避免边缘内容紧贴窗口。 - 移除不必要的大小策略设置:原代码中注释的
scroll.setSizePolicy和wdg.setSizePolicy无需保留,启用setWidgetResizable后,滚动区域与内部widget会自动适配布局。
内容的提问来源于stack exchange,提问作者buhtz
相关产品推荐
相关产品推荐

