Search code examples
pythonpyqt5grid-layout

How to install widgets next to each other in Pyqt5?


In my code there are 2 grids (with buttons and with text fields). The buttons work fine and are in their places, and the text fields, no matter what I do, fall into the upper left corner, and I need them to be to the left of the buttons \under each other\ in 1 column (in the screenshot these are yellow rectangles).

here is my code

import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QVBoxLayout, QHBoxLayout, QSpacerItem, QSizePolicy
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import QCursor, QFont
from PyQt5.QtCore import Qt


class TransparentButton(QLabel):
    def __init__(self, name, parent=None):
        super().__init__(parent)
        self.setAlignment(Qt.AlignCenter)
        self.setStyleSheet("background-color: transparent; color : white;")
        self.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        self.setFont(QFont('Arial', 20))
        self.name = name

        self.value = 0
        self.setText('')

    def mousePressEvent(self, event):
        # проверяем, что нажата нужная кнопка и устанавливаем значение в 20
        if self.name == "Button 1" or self.name == "Button 3" or self.name == "Button 5" or self.name == "Button 7":
            self.value = 20
        else:
            self.value = 10
        self.update_text()

    def update_text(self):
        self.setText(str(self.value))

class EditableLabel(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setAlignment(Qt.AlignCenter)
        self.setStyleSheet("background-color: transparent; color : white;")
        self.setFont(QFont('Arial', 20))
        self.setPlaceholderText("")


class App(QWidget):

    def __init__(self):
        super().__init__()
        self.init_ui()


    def init_ui(self):
    # устанавливаем фоновое изображение
        pixmap = QPixmap("theme_game.png")
        self.setFixedSize(pixmap.width(), pixmap.height()) # устанавливаем фиксированный размер окна
        self.setWindowFlags(Qt.FramelessWindowHint) # убираем рамку окна
        self.setAttribute(Qt.WA_TranslucentBackground) # устанавливаем прозрачный фон
        self.label = QLabel(self)
        self.label.setPixmap(pixmap)
        self.label.setGeometry(0, 0, pixmap.width(), pixmap.height())

        

        # создаем сетку с кнопками
        grid_buttons = QGridLayout(self)
        grid_buttons.setHorizontalSpacing(50)
        grid_buttons.setVerticalSpacing(50)
        names = ['1', 'Bck', 'Button 1', 'Close',
                'Button 3', '8', '9', '/',
                '4', '5', '6', 'Button 5',
                '1', 'Button 7', '3', '-']

        positions = [(i,j) for i in range(4) for j in range(4)]

        for position, name in zip(positions, names):

            if name == '':
                continue
            button = TransparentButton(name)
            grid_buttons.addWidget(button, *position)

        
        vertical_layout = QVBoxLayout()
        for i in range(4):
            text_edit = EditableLabel(self)
            text_edit.setMinimumSize(100, 100)
            text_edit.setMaximumSize(200, 200)
            vertical_layout.addWidget(text_edit)
        vertical_layout.addStretch(1)

        
        
        
        # добавляем вертикальную сетку в основную горизонтальную сетку
        lay = QHBoxLayout()
        lay.addLayout(grid_buttons)
        lay.addLayout(vertical_layout)

        # устанавливаем отступы вокруг сетки кнопок
        self.layout().setContentsMargins(795, 35, 70, 155)
        self.setLayout(lay)

        # перемещаем окно на нужную позицию
        self.move(500, 200)

        self.showFullScreen()


    def resizeEvent(self, event):
        pixmap = QPixmap("theme_game.png")
        self.setFixedSize(pixmap.width(), pixmap.height())
        self.label.setGeometry(0, 0, pixmap.width(), pixmap.height())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = App()
sys.exit(app.exec_())

Screenshot:

enter image description here

I've tried every method I know. I made separate GridLayout grids, tried to add positioning to the loop, and so on. Nothing helps

This is my expectation:

enter image description here


Solution

  • I tried your code and I see removing self in this line might work:

    grid_buttons = QGridLayout(self)
    

    To this:

    grid_buttons = QGridLayout()
    

    This might be a bug happened when you set 1 layout to 2 different widgets (I have not try this before).