Python 如何在PyQt5中使用“移动”命令根据标签的中心而不是左角定位标签

Python 如何在PyQt5中使用“移动”命令根据标签的中心而不是左角定位标签,python,pyqt,Python,Pyqt,嗨,我在Qwidget中有几个Qlabel。我得到了一个我需要在Qt中创建的设计,它实际上只有很少的标签。但其中一个标签的文本是我的更改。因此,文本长度也是可变的。我使用move()命令,它将左角点作为参考点。我想我需要把标签的中心点作为参考点 class App(QWidget): def __init__(self): super().__init__() self.left = 0 self.top = 0 self

嗨,我在Qwidget中有几个Qlabel。我得到了一个我需要在Qt中创建的设计,它实际上只有很少的标签。但其中一个标签的文本是我的更改。因此,文本长度也是可变的。我使用move()命令,它将左角点作为参考点。我想我需要把标签的中心点作为参考点

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.left = 0
        self.top = 0
        self.width = 480
        self.height = 800
        self.initUI()

    def initUI(self):
        #self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)


        # Create widget
        main_page = QLabel(self)
        main_pixmap = QPixmap('main_page')
        main_page.setPixmap(main_pixmap)


        #logo
        logo = QLabel(self)
        logo_pixmap = QPixmap('logo')
        logo.setPixmap(logo_pixmap)
        logo.move(159,63)

        #Date
        today = format_date(datetime.datetime.now(),"dd MMMM", locale = 'tr').upper()
        day = format_date(datetime.datetime.now(), "EEEE", locale = 'tr').upper()
        date = QLabel(self)
        date.setText(day + " " + today )
        date.setFont(QFont("Lato", 24))
        date.setStyleSheet('color:white')
        self.move_to_center()

        #Clock
        clock = QLabel(self)
        clock.setText(strftime('%H:%M'))
        clock.setFont(QFont("Lato", 90))
        clock.setStyleSheet('color:white')
        clock.move(71,222)
如何动态地将标签水平放置在Qwidget的中间

编辑: 当我使用布局时,标签一个接一个地排列起来,如下所示
居中小部件的主要问题是它们可以根据内容改变大小

对于您的案例,更简单的解决方案是创建一个具有固定宽度且文本中心对齐的标签:

        clock = QLabel(self)
        clock.setText(strftime('%H:%M'))
        clock.setFixedWidth(self.width())
        clock.move(0, 222)
        clock.setAlignment(Qt.AlignCenter)
虽然这很好,但有几个问题:

  • 如果标签有多条线,并且您不希望它跨越整个宽度,则对齐将始终居中(这可能很难看)
  • 如果原始文本在一行,而新文本有更多行,则无法正确更新(除非在每次文本更改后调用
    label.adjustSize()
另一种解决方案是创建QLabel的子类,该子类在显示或更改文本时自动重新定位自身:

class CenterLabel(QLabel):
    vPos = 0
    def setText(self, text):
        super(CenterLabel, self).setText(text)
        if self.parent():
            self.center()

    def setVPos(self, y):
        # set a vertical reference point
        self.vPos = y
        if self.parent():
            self.center()

    def center(self):
        # since there's no layout, adjustSize() allows us to update the
        # sizeHint based on the text contents; we cannot use the standard
        # size() as it's unreliable when there's no layout
        self.adjustSize()
        x = (self.parent().width() - self.sizeHint().width()) / 2
        self.move(x, self.vPos)
尽管如此,我仍然认为使用布局是一个更好、更简单的解决方案。您只需创建“背景”pixmap,将主小部件作为父部件,而不将其添加到布局中,然后设置布局并使用
layout.addSpacing
添加所有小部件之间的垂直间距

这里唯一的问题是,如果标签文本更改其行数,则所有后续小部件都将相应地移动。如果是这种情况,只需为小部件设置一个固定高度,该高度等于小部件顶部和下一个小部件顶部之间的距离,然后将小部件添加到布局中,确保其水平居中且顶部对齐

    def initUI(self):
        #self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self._width, self._height)

        self.background = QLabel(self)
        self.background.setPixmap(QPixmap('background.png'))

        layout = QVBoxLayout()
        self.setLayout(layout)
        # set spacing between items to 0 to ensure that there are no added margins
        layout.setSpacing(0)

        # add a vertical spacing for the top margin;
        # I'm just using random values
        layout.addSpacing(20)

        main_page = QLabel(self)
        main_pixmap = QPixmap('main_page')
        main_page.setPixmap(main_pixmap)
        # add the widget ensuring that it's horizontally centered
        layout.addWidget(main_page, alignment=Qt.AlignHCenter)

        #logo
        logo = QLabel(self)
        logo_pixmap = QPixmap('logo')
        logo.setPixmap(logo_pixmap)
        layout.addWidget(logo, alignment=Qt.AlignHCenter)

        layout.addSpacing(50)

        #Date
        today = format_date(datetime.datetime.now(),"dd MMMM", locale = 'tr').upper()
        day = format_date(datetime.datetime.now(), "EEEE", locale = 'tr').upper()
        date = QLabel(self)
        date.setText(day + " " + today )
        date.setFont(QFont("Lato", 24))
        date.setStyleSheet('color:white')
        # set a fixed height equal to the vertical position of the next label
        date.setFixedHeight(100)
        # ensure that the label is always on top of its layout "slot"
        layout.addWidget(date, alignment=Qt.AlignHCenter|Qt.AlignTop)

        #Clock
        clock = QLabel(self)
        clock.setText(strftime('%H:%M'))
        clock.setFont(QFont("Lato", 90))
        clock.setStyleSheet('color:white')
        layout.addWidget(clock, alignment=Qt.AlignHCenter|Qt.AlignTop)

        # add a bottom "stretch" to avoid vertical expanding of widgets
        layout.addStretch(1000)

“动态”是指一旦程序启动,标签的文本可能会在某个点发生变化?不使用布局有什么具体原因吗?是的@musicamante,标签将代表日期和用户名,因此它们的文本将发生变化。没有理由不使用布局。我只需要重新创建我得到的精确设计。为此,我认为应该使用坐标(使用
move()
函数)。有不同的方法可以重新创建“精确设计”(特别是在这个“响应式”设计的时代)。在您的计算机上重新创建精确设计的字体可能没有问题,但在另一台计算机上可能没有问题,特别是当用户具有不同的默认字体或DPI设置时。此外,您没有设置固定的大小,只设置了一个几何体,这样就有可能调整大小(如果需要,由用户甚至系统调整大小),这显然会让一切变得丑陋。“精确设计”真的是强制性的吗?或者你只是因为无法通过布局实现而使用它?因为它完全可以与他们一起使用。@musicamante它是一个用于读卡器的信息亭应用程序。所以实际上没有用户。