Настройка выравнивания виджетов при добавлении их в макет не влияет на выравнивание виджетов, а только на их выравнивание в пределах пространства, которое макет предоставляет им. Кроме того, многие виджеты автоматически пытаются расширить себя (например, QLabels или представления элементов).
Например, QLabel имеет выравнивание текста по умолчанию влево / вертикально по центру, поэтому вам нужно установить that выравнивания, но он все равно будет пытаться расширить свое доступное пространство, если это позволят другие виджеты.
Чтобы получить то, что вам нужно, вы должны учитывать расстояние между виджетами, их sizePolicy
(что представляет собой «Готовность» виджета к его размеру при использовании в макете, если он имеет фиксированный размер, может ли он увеличиваться / увеличиваться, может ли он уменьшаться и т. д. c).
Поскольку требуется некоторое пространство между столбцы, самое простое, что нужно сделать, это оставить пустые столбцы в макете и установить для этих столбцов коэффициент растяжения , используя setColumnStretch()
, чтобы они пытались расширить как можно больше насколько это возможно.
Наконец, для сложных структур всегда лучше использовать вложенные макеты, что означает, что у вас будет установлен основной макет для виджета, а "child" la Вы добавляете его, так что каждый «раздел» имеет свой собственный менеджер макета, независимый от других. В следующем примере я реализовал такую структуру:
+-------------- main vertical layout ---------------+
| |
| +------------ button grid layout -------------+ |
| |title| |(empty)| |(empty)| |title| |
| +-----+----+-------+------+-------+-----+-----+ |
| |label|edit| |input | |label|edit | |
| +-----+----+-------+------+-------+-----+-----+ |
| |label|edit| |input | |label|edit | |
| +-----+----+-------+------+-------+-----+-----+ |
| |label|edit| |input | |label|edit | |
| +-----+----+-------+------+-------+-----+-----+ |
+---------------------------------------------------+
| |
| +---------- graph horizontal layout ----------+ |
| | | | |
| | left graph | right graph | |
| | | | |
| +----------------------+----------------------+ |
+---------------------------------------------------+
| |
| +--------- button horizontal layout ----------+ |
| | | | | |
| | button | (stretch) | button | |
| | | | | |
| +--------+---------------------------+--------+ |
+---------------------------------------------------+
Вот как это выглядит:
И это это код. Обратите внимание, что я удалил создание виджетов из init (если вы используете функцию initUi
, не имеет большого смысла создавать их в другом месте).
from PyQt5 import QtWidgets, QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import sys
class Okno(QtWidgets.QMainWindow):
def __init__(self):
super(Okno, self).__init__()
self.setGeometry(500, 500, 900, 500)
self.setWindowTitle("My window")
self.iniUI()
def iniUI(self):
w = QtWidgets.QWidget()
self.setCentralWidget(w)
mainLayout = QtWidgets.QVBoxLayout(w)
grid = QtWidgets.QGridLayout()
mainLayout.addLayout(grid)
self.dataInputLabel = QtWidgets.QLabel('Data Input')
grid.addWidget(self.dataInputLabel, 0, 0)
self.dataInputLabel.setStyleSheet('color: red')
portSettingLabel = QtWidgets.QLabel('Port setting', alignment=QtCore.Qt.AlignCenter)
grid.addWidget(portSettingLabel, 0, 3)
self.dataOutputLabel = QtWidgets.QLabel('Data Output', alignment=QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter)
grid.addWidget(self.dataOutputLabel, 0, 6)
self.dataOutputLabel.setStyleSheet('color: blue')
# set the vertical policy to Maximum for labels, so they don't try to
# expand themselves if there's more available space
for label in (self.dataInputLabel, portSettingLabel, self.dataOutputLabel):
label.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
grid.addWidget(QtWidgets.QLabel('Pressure [kPa]'), 1, 0)
self.inputPressure = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.inputPressure, 1, 1)
grid.addWidget(QtWidgets.QLabel('Temperature [K]'), 2, 0)
self.inputTemp = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.inputTemp, 2, 1)
grid.addWidget(QtWidgets.QLabel('Humidity [%]'), 3, 0)
self.inputHumidity = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.inputHumidity, 3, 1)
self.portEdit = QtWidgets.QLineEdit(placeholderText='Enter port')
grid.addWidget(self.portEdit, 1, 3)
self.baudEdit = QtWidgets.QLineEdit(placeholderText='Baudrate')
grid.addWidget(self.baudEdit, 2, 3)
self.parityEdit = QtWidgets.QLineEdit(placeholderText='Parity')
grid.addWidget(self.parityEdit, 3, 3)
grid.addWidget(QtWidgets.QLabel('Pressure [kPa]'), 1, 5)
self.outputPressure = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.outputPressure, 1, 6)
grid.addWidget(QtWidgets.QLabel('Temperature [K]'), 2, 5)
self.outputTemp = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.outputTemp, 2, 6)
grid.addWidget(QtWidgets.QLabel('Humidity [%]'), 3, 5)
self.outputHumidity = QtWidgets.QLineEdit(readOnly=True)
grid.addWidget(self.outputHumidity, 3, 6)
grid.setColumnStretch(2, 1)
grid.setColumnStretch(4, 1)
graphLayout = QtWidgets.QHBoxLayout()
mainLayout.addLayout(graphLayout)
# here insert your graphs...
self.graphLeft = FigureCanvas(Figure())
graphLayout.addWidget(self.graphLeft)
self.graphRight = FigureCanvas(Figure())
graphLayout.addWidget(self.graphRight)
buttonLayout = QtWidgets.QHBoxLayout()
mainLayout.addLayout(buttonLayout)
self.openButton = QtWidgets.QPushButton('Open file')
self.openButton.setMinimumWidth(150)
self.openButton.clicked.connect(self.open_file)
buttonLayout.addWidget(self.openButton)
# add an empty "stretch", which acts as an expanding spacer on box layouts
buttonLayout.addStretch()
self.exitButton = QtWidgets.QPushButton('Exit')
self.exitButton.clicked.connect(self.close)
buttonLayout.addWidget(self.exitButton)
Наконец рассмотрите возможность использования Qt Designer, который полезен для создания сложных макетов (или, по крайней мере, визуализируйте их в процессе их проектирования, если вы все еще хотите делать все с помощью кода). Обратите внимание, что в этом случае вы должны следовать рекомендациям, предложенным для с использованием Designer (самое главное, никогда редактировать файлы python, созданные с помощью утилиты pyuic
), или использовать loadUi('yourguifile.ui', self)
(где self
- это виджет / окно, которое вы хотите настроить с помощью пользовательского интерфейса) из модуля PyQt5.uic
.