我似乎无法理解它们是如何工作的。放置多个小部件的最佳选择似乎是 QGridLayout,但是当我将一些东西添加到特定的行/列中,然后决定将一些东西添加到另一行/列中时,一切都会发生变化,这真的很令人沮丧。
例如,我什至不能做像谷歌主页这样简单的布局。当我将搜索栏添加到我想要的位置,然后在其上方添加图像/文本时,所有内容都会移动到奇怪的地方等,我无法在网上找到有关如何处理它的正确解释。因此,如果有人能以一种可以理解的方式向像我这样的绝对初学者解释它,我会很高兴。
所以当我有以下代码时:
from PyQt6.QtWidgets import *
import sys
import numpy as np
import os
from PyQt6 import QtCore, QtGui
from PyQt6.QtCore import QEvent, Qt
from PyQt6.QtGui import QPalette, QColor
from pathlib import Path
app = QApplication(sys.argv)
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.resize(1024, 768)
self.setWindowTitle("Tracker")
layout = QGridLayout()
self.setLayout(layout)
#layout.setRowMinimumHeight(0, 50)
#layout.setColumnMinimumWidth(0,50)
self.input = QLineEdit(self)
self.input.setPlaceholderText('Enter Username')
layout.addWidget(self.input,1,1)
self.input.setFixedSize(300,30)
self.darkmode_check = QCheckBox('Darkmode',self)
self.darkmode_check.toggled.connect(self.darkmode)
self.darkmode_check.setChecked(True)
self.darkmode_check.move(0,0)
def darkmode(self):
if self.darkmode_check.isChecked() == True:
app.setStyleSheet(Path('D:\CODE\League Code\darkorange.qss').read_text())
else:
app.setStyleSheet(Path('D:\CODE\League Code\classic_edit.qss').read_text())
window = MainWindow()
window.show()
sys.exit(app.exec())
我得到了这个屏幕,这就是我想要的。
当我只想在此搜索栏上方添加文本时:
通过添加
self.text = QLabel(self)
self.text.setText('Tracker')
layout.addWidget(self.text,0,1)
我明白了:
到处都是。
有没有人对GridLayout有很好的解释或者可以推荐好的网站?我发现了很多关于网格的外观等但没有任何帮助(还有一些帖子给了我 3x3 网格,一些 4x4 等,我在这一点上很困惑) 我基本上只想在中间放置一个搜索栏,然后在上面放置一个文本,然后继续在这里和那里添加一些小东西。
谢谢
Qt 基本布局总是尝试 均匀 在其“单元格”中分配可用空间,并且每个小部件都会保留该空间(即使它没有使用所有空间)。
请注意,不同的小部件类型也有不同的大小策略告诉布局它应该如何分配可用空间并最终设置这些小部件的几何形状。
例如,QLineEdit 有一个
Fixed
vertical policy,这意味着它的大小提示将始终被视为唯一有效的高度(类似于调用 setFixedHeight()
或 setFixedSize()
)。
QLabel 相反,有一个
Preferred
大小策略,这意味着如果布局中有剩余空间,它可以利用它。
当你只有行编辑时,布局只有那个小部件,所以它会把它放在中心(因为你没有指定对齐方式)。但是当你添加标签时,布局发现行编辑需要非常小的空间,所以它会将剩余的空间留给标签,因此你的结果。
对于像这样的简单情况,您可以在添加小部件时指定适当的对齐方式:提供对齐方式时,项目不会尝试占据整个单元格,布局会将其对齐到该布局单元格的可用空间.
layout.addWidget(self.text, 0, 0, alignment=Qt.AlignBottom)
layout.addWidget(self.input, 1, 0, alignment=Qt.AlignTop)
请注意,我将列更改为 0,因为如果第一列中没有任何内容,则将小部件放置在second列中没有意义,除非您想利用
setColumnStretch()
或setColumnMinimumWidth()
。
还要考虑到对于这种有很多空白空间的“宽”布局,通常最好使用嵌套布局或使用容器小部件。
例如:
layout = QGridLayout(self)
centerLayout = QVBoxLayout()
layout.addLayout(centerLayout, 0, 0, alignment=Qt.AlignCenter)
# ...
centerLayout.addWidget(self.text)
centerLayout.addWidget(self.input)
或者,或者:
layout = QGridLayout(self)
centerWidget = QWidget()
layout.addWidget(centerWidget, 0, 0, alignment=Qt.AlignCenter)
centerLayout = QVBoxLayout(centerWidget)
# ... as above
试着去掉上面两个例子中的
alignment
参数,你会发现区别。
我建议你在 Qt Designer 中使用 layouts 做一些实验,这样可以更容易地立即理解布局如何工作以及如何与不同的 widget 类型一起工作。