阻止小部件相互重叠并在它们之间添加 space
Stop widgets from overlapping each other and add space between them
我正在使用 QHBoxLayout
进行布局。细分是:pic.1 是发生了什么,pic.2 是我想要的 - 小部件不重叠并且它们之间存在间隙。对于图 2,我创建了一个 Gap
小部件以粘贴在现有小部件之间。但这是一个麻烦的解决方案,需要额外的维护(特别是当我有两个以上的小部件需要照顾时)。此外,由于 B 与 A 重叠,我认为新添加的间隙小部件也与 A 重叠,可能根据其大小的分数。我不太确定。
我试过使用 self.layout.addSpacing(10)
,但这不起作用。红色小部件从之前的位置移动了 10 个像素,而不是从左侧小部件的边框移动。
另请注意,包含的小部件都有一些最小宽度规范。
那么,如何在图 2 中的两个小部件之间添加 space?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Gap(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setMinimumWidth(10)
self.setMinimumHeight(1)
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
# Set layout
self.layout = QHBoxLayout()
self.setLayout(self.layout)
# Set palette
self.palette1 = QPalette()
self.palette1.setColor(QPalette.Window, Qt.red)
self.palette2 = QPalette()
self.palette2.setColor(QPalette.Window, Qt.blue)
self.palettebg = QPalette()
self.palettebg.setColor(QPalette.Window, Qt.green)
self.setAutoFillBackground(True)
self.setPalette(self.palettebg)
# Set labels
self.label1 = QLabel(self)
self.label1.setText("A")
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.adjustSize()
self.label1.setAutoFillBackground(True)
self.label1.setPalette(self.palette1)
self.label1.setMinimumSize(36, 36)
self.label2 = QLabel(self)
self.label2.setText("B")
self.label2.move(30, 0)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.adjustSize()
self.label2.setAutoFillBackground(True)
self.label2.setPalette(self.palette2)
self.label2.setMinimumSize(36, 36)
self.gap = Gap()
self.layout.addWidget(self.label1)
# self.layout.addWidget(self.gap)
# self.layout.addSpacing(10)
self.layout.addWidget(self.label2)
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5'
self.left = 10
self.top = 10
self.width = 200
self.height = 54
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.line = Line(self)
self.line.resize(74, 54)
self.line.move(50, 50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# CUSTOM
app.setFont(QFontDatabase().font("Monospace", "Regular", 14))
ex = App()
sys.exit(app.exec_())
编辑 澄清,按要求:(1)假设父窗口小部件的大小太小(并且无法调整大小),(2)父窗口小部件具有 QHBoxLayout 与向其中添加了小部件 A 和 B,(3) 父小部件太小,QHBoxLayout 将子小部件 A 和 B 排列成彼此重叠,如第一张图片所示。 (4) 这种重叠是不可取的,widgets只需要一个接一个放置,没有重叠,中间有间隙,如图2。我不知道QHBoxLayout如何做到这一点。
EDIT 2 这是一个直观的解释。
这里的绿色是父窗口小部件 - 假设无法调整大小。添加了小部件 A:
添加小部件 B:
现在,小部件 B 在 A 之上。我不想要它。我想要这个:
子widget的minimumSize不影响父widget的minimumSize,布局的使用也不影响widget的minimumSize。布局设置 minimumSizeHint 和 sizeHint,使用处理的小部件的 minimumSize 以及其他功能(例如大小和调整大小策略)作为信息。因此,在第一个实例中,您必须将父小部件的 minimumSize 设置为它的 minimumSizeHint。
另一方面,布局默认有间距,因此建议将其设置为 0。
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
# Set layout
layout = QHBoxLayout(self, spacing=0)
layout.addWidget(self.label1)
layout.addSpacing(10)
layout.addWidget(self.label2)
self.setMinimumSize(self.minimumSizeHint())
# or
# layout = QHBoxLayout(self, spacing=10)
# layout.addWidget(self.label1)
# layout.addWidget(self.label2)
# self.setMinimumSize(self.minimumSizeHint())
更新:
可以处理的布局的最大尺寸是父部件的尺寸,所以在这种情况下它会压缩而不考虑空间,一个解决方案是设置一个部件作为内容,并且在那建立布局,因此布局将自由延伸到内容小部件。
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
content_widget = QWidget(self)
layout = QHBoxLayout(content_widget, spacing=10)
layout.addWidget(self.label1)
layout.addWidget(self.label2)
content_widget.setFixedSize(content_widget.minimumSizeHint())
我正在使用 QHBoxLayout
进行布局。细分是:pic.1 是发生了什么,pic.2 是我想要的 - 小部件不重叠并且它们之间存在间隙。对于图 2,我创建了一个 Gap
小部件以粘贴在现有小部件之间。但这是一个麻烦的解决方案,需要额外的维护(特别是当我有两个以上的小部件需要照顾时)。此外,由于 B 与 A 重叠,我认为新添加的间隙小部件也与 A 重叠,可能根据其大小的分数。我不太确定。
我试过使用 self.layout.addSpacing(10)
,但这不起作用。红色小部件从之前的位置移动了 10 个像素,而不是从左侧小部件的边框移动。
另请注意,包含的小部件都有一些最小宽度规范。
那么,如何在图 2 中的两个小部件之间添加 space?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Gap(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setMinimumWidth(10)
self.setMinimumHeight(1)
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
# Set layout
self.layout = QHBoxLayout()
self.setLayout(self.layout)
# Set palette
self.palette1 = QPalette()
self.palette1.setColor(QPalette.Window, Qt.red)
self.palette2 = QPalette()
self.palette2.setColor(QPalette.Window, Qt.blue)
self.palettebg = QPalette()
self.palettebg.setColor(QPalette.Window, Qt.green)
self.setAutoFillBackground(True)
self.setPalette(self.palettebg)
# Set labels
self.label1 = QLabel(self)
self.label1.setText("A")
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.adjustSize()
self.label1.setAutoFillBackground(True)
self.label1.setPalette(self.palette1)
self.label1.setMinimumSize(36, 36)
self.label2 = QLabel(self)
self.label2.setText("B")
self.label2.move(30, 0)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.adjustSize()
self.label2.setAutoFillBackground(True)
self.label2.setPalette(self.palette2)
self.label2.setMinimumSize(36, 36)
self.gap = Gap()
self.layout.addWidget(self.label1)
# self.layout.addWidget(self.gap)
# self.layout.addSpacing(10)
self.layout.addWidget(self.label2)
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5'
self.left = 10
self.top = 10
self.width = 200
self.height = 54
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.line = Line(self)
self.line.resize(74, 54)
self.line.move(50, 50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# CUSTOM
app.setFont(QFontDatabase().font("Monospace", "Regular", 14))
ex = App()
sys.exit(app.exec_())
编辑 澄清,按要求:(1)假设父窗口小部件的大小太小(并且无法调整大小),(2)父窗口小部件具有 QHBoxLayout 与向其中添加了小部件 A 和 B,(3) 父小部件太小,QHBoxLayout 将子小部件 A 和 B 排列成彼此重叠,如第一张图片所示。 (4) 这种重叠是不可取的,widgets只需要一个接一个放置,没有重叠,中间有间隙,如图2。我不知道QHBoxLayout如何做到这一点。
EDIT 2 这是一个直观的解释。
这里的绿色是父窗口小部件 - 假设无法调整大小。添加了小部件 A:
添加小部件 B:
现在,小部件 B 在 A 之上。我不想要它。我想要这个:
子widget的minimumSize不影响父widget的minimumSize,布局的使用也不影响widget的minimumSize。布局设置 minimumSizeHint 和 sizeHint,使用处理的小部件的 minimumSize 以及其他功能(例如大小和调整大小策略)作为信息。因此,在第一个实例中,您必须将父小部件的 minimumSize 设置为它的 minimumSizeHint。
另一方面,布局默认有间距,因此建议将其设置为 0。
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
# Set layout
layout = QHBoxLayout(self, spacing=0)
layout.addWidget(self.label1)
layout.addSpacing(10)
layout.addWidget(self.label2)
self.setMinimumSize(self.minimumSizeHint())
# or
# layout = QHBoxLayout(self, spacing=10)
# layout.addWidget(self.label1)
# layout.addWidget(self.label2)
# self.setMinimumSize(self.minimumSizeHint())
更新:
可以处理的布局的最大尺寸是父部件的尺寸,所以在这种情况下它会压缩而不考虑空间,一个解决方案是设置一个部件作为内容,并且在那建立布局,因此布局将自由延伸到内容小部件。
class Line(QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent, autoFillBackground=True)
# Set palette
palette1 = QPalette()
palette1.setColor(QPalette.Window, Qt.red)
palette2 = QPalette()
palette2.setColor(QPalette.Window, Qt.blue)
palettebg = QPalette()
palettebg.setColor(QPalette.Window, Qt.green)
self.setPalette(palettebg)
# Set labels
self.label1 = QLabel(text="A", autoFillBackground=True)
self.label1.setStyleSheet('font-size: 36pt;')
self.label1.setPalette(palette1)
self.label1.setMinimumSize(36, 36)
self.label1.adjustSize()
self.label2 = QLabel(text="B", autoFillBackground=True)
self.label2.setStyleSheet('font-size: 36pt;')
self.label2.setPalette(palette2)
self.label2.setMinimumSize(36, 36)
self.label2.adjustSize()
content_widget = QWidget(self)
layout = QHBoxLayout(content_widget, spacing=10)
layout.addWidget(self.label1)
layout.addWidget(self.label2)
content_widget.setFixedSize(content_widget.minimumSizeHint())