Search code examples
pythonqlabelpyside6

How to show a lable at specific co-ordinate in PySide6


Suppose I have this label

text = QtWidgets.QLabel("Hello World")

Now I want to show this label at a co-ordinate of 100, 90 meaning I want its top-left most pixel at that co-ordinate. How can I do that?

I already tried using indent but it seems that it pushes the object 100 pixels in both x and y direction

text = QtWidgets.QLabel("Hello World", indent = 100)

Is there something like

text.exec(QtCore.QPoint(100, 90))

Extra information: this example was given PySide docs

import sys
import random
from PySide6 import QtCore, QtWidgets, QtGui


class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
        self.button = QtWidgets.QPushButton("File")
        self.text = QtWidgets.QLabel("Hello World")
        self.layout = QtWidgets.QVBoxLayout(self)
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.magic)

    @QtCore.Slot()
    def magic(self):
        self.text.setText(random.choice(self.hello))

if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(800, 600)
    widget.show()

    sys.exit(app.exec())

Solution

  • For this specific case, it can be enough to set the padding of the stylesheet:

    self.text.setStyleSheet('padding-left: 100px; padding-top: 90px;')
    

    Alternatively, using the contents margin might work, but it's not guaranteed for all widgets and all OS and styles:

    self.text.setContentsMargins(100, 90, 0, 0)
    

    In that case, it's possible to add the widget into a layout and add that layout to the main one instead:

    textLayout = QtWidgets.QVBoxLayout()
    textLayout.setContentsMargins(100, 90, 0, 0)
    textLayout.addWidget(self.text)
    self.layout.addLayout(textLayout)
    

    Be aware that all this won't ensure that the widget will always stay at that position in case the parent size is increased. A possible solution could be to set the maximum size based on the hint:

    # after setting the margins
    self.text.setMaximumSize(self.text.sizeHint)
    

    Note that this must be called every time the text of the label is changed.