Skip to content
Advertisement

Move pyqt button out of list of buttons

I have a list of pyqt4 push button and want to move the position. Since it is troublesome it make lots of buttons variable I create them through a list. The code below

import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout(self)

        self.buttons = []
        for i in range(3):
            self.buttons.append(QPushButton('',self))
            self.buttons[-1].setFixedWidth(50)
            self.buttons[-1].setFixedHeight(50)
            self.buttons[-1].move(70*i+50,300)
            layout.addWidget(self.buttons[-1])


if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.resize(500,500)
    window.show()
    sys.exit(app.exec_())

don’t work for specify the position Image 1

but

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout(self)

        self.button1 = QPushButton('',self)
        self.button1.setFixedWidth(50)
        self.button1.setFixedHeight(50)
        self.button1.move(50,300)

        self.button2 = QPushButton('',self)
        self.button2.setFixedWidth(50)
        self.button2.setFixedHeight(50)
        self.button2.move(120,300)

        self.button3 = QPushButton('',self)
        self.button3.setFixedWidth(50)
        self.button3.setFixedHeight(50)
        self.button3.move(190,300)

        layout = QVBoxLayout(self)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)

works fine.

Image 2

What’s the reason behind?

Advertisement

Answer

If you want to manually specify the geometry (position and size) of widgets, you should not add them to a layout.

Your second example “works” just because you already created and set a layout to the top-level widget (the Window class), and since a layout already exists the second one is not “installed”. Running it from the console will shows this error:

StdErr: QLayout: Attempting to add QLayout “” to Window “”, which already has a layout

When a widget is added to a layout, the ownership of the “layout item” (an abstract item used by layouts to manage its widgets) is transferred to the layout, and the widget is reparented to the widget that uses that layout.

Since the second layout cannot be set, it will not manage the geometries of the items you tried to add, and the result is that they will keep the geometries you set before.

The same result can be obtained if you remove all the last lines referencing the other layout, which is exactly what you need.

Also, note that in order to add a widget that is not managed by a layout, a parent is required. Your last example also works because you specified the window as the parent while instantiating them; if you don’t do that the buttons will not be shown, but if you do show them (with show() or setVisible(True)) they will each appear in separate windows, as they will become their own top level windows.

If you don’t have other widgets that should be managed by a layout, you can also avoid creating the first layout at all (but, still, the parent is required).

Finally, let me tell you that using manual geometries is generally discouraged, and there are very few and specific cases for which it’s a good idea to go with.
The main reason behind this is that widgets tend to show very differently from device to device, and that depends on various aspects:

  • different OS and OS versions draw widgets differently (sometimes dramatically), and this involves varying the widget size and behavior; while this might not be a major issue for simple widgets, it can be a problem for things like item views, spinboxes, etc;
  • different OS and systems use different styles, which also includes things like internal widget content margins and minimum size;
  • specific system settings (most importantly, the default font) could make widgets mostly unreadable, specifically with text being clipped within the widget margins if the font size is too big;
  • depending on the OS, you might face issues if the system uses High DPI displays, and you could end up with very tiny widgets that are almost impossible to interact with;
  • fixed geometries force you (and the user) to have a fixed widget/window size, and (along with the DPI issue above) this can be a problem: the same widget could look too big or too small;
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement