Есть ли альтернатива QGridLayout, которая поддерживает точное размещение по сетке?
Если использовать QGridLayout и пробовать разместить элементы в разных местах, например так:
button1 = QPushButton('0, 0')
button2 = QPushButton('2, 4')
grid.addWidget(button1, 0, 0)
grid.addWidget(button2, 2, 4)
Тогда они разместятся рядом друг с другом, а не по заданным ячейкам.
Есть ли такой лей-аут, где элементы располагаются по заданным позициям?
Виджет QStackedWidget мне не подходит.
Ответы (2 шт):
Автор решения: Maxim Timakov
→ Ссылка
Один из вариантов("костылей") - использование setRowMinimumHeight / setColumnMinimumWidth
def insert_widget_to_grid(grid: QGridLayout, widget: QWidget, row: int, col: int)
c_rows: int = grid.rowCount()
c_cols: int = grid.columnCount()
# expand table
DEF_HEIGHT = 42
DEF_WIDTH = 42
while c_rows <= row:
grid.setRowMinimumHeight(c_rows, DEF_HEIGHT)
c_rows += 1
while c_cols <= row:
grid.setColumnMinimumWidth(c_cols, DEF_WIDTH)
c_cols += 1
# insert widget
grid.addWidget(widget, row, col)
Тестовый код на C++
#include "widget.h"
#include <QGridLayout>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
auto grid = new QGridLayout;
for(int i = 0; i < 10; ++i)
{
grid->setColumnMinimumWidth(i, 30);
grid->setRowMinimumHeight(i, 30);
}
auto b_00 = new QPushButton{"00, 00"};
auto b_44 = new QPushButton{"04, 04"};
grid->addWidget(b_00, 0, 0);
grid->addWidget(b_44, 4, 4);
setLayout(grid);
}
Widget::~Widget() {}
Автор решения: S. Nick
→ Ссылка
Я увидел вашу задачу так. Поменяйте импорты на свои и попродуйте.
main.py:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Frame(QtWidgets.QFrame):
def __init__(self, num, size):
super().__init__()
self.setMinimumSize(*size)
self.layout = QtWidgets.QGridLayout(self)
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setObjectName('mainwidget')
many_cells = 15 # хотим создать 15 ячеек
column = 5 # хотим разместить эти ячееки в 5 колонки
size = (80, 80) # размер ячееки, например 80х80
self.dict_cells_widgets = {}
grid = QtWidgets.QGridLayout(self)
for step in range(many_cells):
cell = Frame(step+1, size)
row = step // column
col = step % column
cell.setObjectName(f'frame_{row}_{col}')
grid.addWidget(cell, row, col)
self.dict_cells_widgets[row, col] = cell
_list = (0, 0), (2, 4)
for (row, col) in _list:
cell = self.dict_cells_widgets[row, col]
button = QtWidgets.QPushButton(f'{row}, {col}')
button.clicked.connect(
lambda ch, row=row, col=col: print(row, col))
cell.layout.addWidget(button, 1, 1)
QSS = '''
QPushButton {
font-size: 12pt;
background-color: #ccffbd;
}
QFrame {
background-color: #dbafbd;
}
#mainwidget {
background-color: #55afbd;
}
#frame_2_0 {
background-color: translate;
}
#frame_0_4 {
border-image: url(opencv_color.jpg) 0 0 0 0 stretch stretch;
}
'''
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
app.setStyleSheet(QSS)
w = MainWindow()
w.resize(400, 280)
w.show()
sys.exit(app.exec_())
opencv_color.jpg



