Search code examples
pythonpyqt5windowqpushbuttonqmainwindow

PyQt5: attach button position to the window coordinates


So, I'm trying to experiment a bit with PyQt5. I have created a basic window with two QPushButtons.

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy
import sys

class Okno(QMainWindow):
    def __init__(self):
        super(Okno, self).__init__()
        self.setGeometry(500, 500, 900, 500)  # window size setGeometry(xpos, ypos, w, h)
        # self.setFixedSize(900, 500) # fix window position
        self.setWindowTitle("My window")
        self.label = QtWidgets.QLabel(self)
        self.button1 = QtWidgets.QPushButton(self)
        self.button2 = QtWidgets.QPushButton(self)
        self.iniUI()

    # Buttons
    def iniUI(self):
        self.button1.setText("Open file")
        self.button1.move(75, 450)
        self.button1.setMinimumWidth(150)
        self.button1.clicked.connect(Button_events.open_file)  # add (connect) button event 

        self.button2.setText("Exit")
        self.button2.move(750, 450)
        self.button2.clicked.connect(exit)

# Button events
class Button_events(QMainWindow):
    def open_file(self):
        print("Open file")

# Main method
def window():
    app = QApplication(sys.argv)
    okno = Okno()
    okno.show()
    sys.exit(app.exec_())


window()

I have set button's position by absolute coordinates. When I resize My Window, the button simply holds its absolute coordinates.

How can I attach the button's coordinates to My Window, so when I scale the window, the button would move within.

Is it possible to set a minimum My Window size with respect to minimum QPushButtons size (when buttons won't fit My Window, it can't be adjusted any smaller)?

Here is a simple screen of what I'm trying to achieve (the original buttons are cut in half, they would disappear if My Window gets any smaller):

enter image description here

Thank you.


Solution

  • I would recommend using a layout to handle the position of all the widgets and minimum size of the window. With QGridLayout, you can align the buttons to the bottom left and bottom right.

    from PyQt5 import QtWidgets, QtCore
    from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy
    import sys
    
    class Okno(QMainWindow):
        def __init__(self):
            super(Okno, self).__init__()
            self.setGeometry(500, 500, 900, 500)
            self.setWindowTitle("My window")
            self.label = QtWidgets.QLabel()
            self.button1 = QtWidgets.QPushButton()
            self.button2 = QtWidgets.QPushButton()
            self.iniUI()
    
        # Buttons
        def iniUI(self):
            w = QtWidgets.QWidget()
            self.setCentralWidget(w)
            grid = QtWidgets.QGridLayout(w)
    
            self.button1.setText("Open file")
            self.button1.setMinimumWidth(150)
            self.button1.clicked.connect(self.open_file)
            self.button2.setText("Exit")
            self.button2.clicked.connect(self.close)
    
            grid.addWidget(self.button1, 0, 0, QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom)
            grid.addWidget(self.button2, 0, 1, QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom)
    
        def open_file(self):
            print("Open file")
    
    
    def window():
        app = QApplication(sys.argv)
        okno = Okno()
        okno.show()
        sys.exit(app.exec_())
    
    window()