在布局中居中 QLabel

Centering QLabel inside layout

我试图将显示 QWidget 内的像素图的 QLabel 水平和垂直居中,但出于某种原因,这似乎是不可能的。我读过很多类似的问题,似乎它们都归结为在将标签添加到布局时指定对齐方式。好吧,我正在这样做,但它仍然与左上角对齐。有人可以帮我把我该死的 QLabel 居中吗? :)

main.py

import sys
from PyQt5.QtWidgets import QApplication
from mainwindow import MainWindow

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

mainwindow.py

from PyQt5.QtGui import QGuiApplication, QWheelEvent
from PyQt5.QtWidgets import QMainWindow
from imagewidget import ImageWidget


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.resize(QGuiApplication.primaryScreen().availableSize() * 3 / 5)

        self.image_widget = ImageWidget()
        self.setCentralWidget(self.image_widget)

    def wheelEvent(self, event: QWheelEvent) -> None:
        angleDelta = event.angleDelta().y()

        if angleDelta >= 0:
            self.image_widget.zoomIn()
        else:
            self.image_widget.zoomOut()

imagewidget.py

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPalette
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy, QPushButton


class ImageWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.scale_factor = 1.0
        self.label = QLabel()
        self.label.setAlignment(Qt.AlignVCenter)
        self.label.setPixmap(QPixmap("image.png"))  # Loads local test image
        self.label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self.label.setScaledContents(True)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.label, Qt.AlignCenter)  # Why does this not align the label to the center of the layout?
        self.setLayout(self.layout)

    def zoomIn(self):
        self.scale_factor *= 1.1
        self.resizeUsingScaleFactor()

    def zoomOut(self):
        self.scale_factor /= 1.1
        self.resizeUsingScaleFactor()

    def getImageSize(self):
        return self.label.pixmap().size()

    def resizeUsingScaleFactor(self):
        self.label.resize(self.getImageSize() * self.scale_factor)

当您调整小部件的大小时,它不会调整其位置,它只是 调整大小。所有小部件都基于原点(左上角)设置它们的几何形状,如果您使用 resize 原点将始终保持不变。

由于您使用的是布局,因此您应该将定位留给布局(因为您使用的是 Ignore 大小策略,所以您也在阻止这种情况,这在这些情况下是个问题。另请注意您正在使用对齐作为 addWidget 的第二个参数,但它的签名是 addWidget(widget, stretch=0, alignment=Qt.Alignment()),因此您应该使用正确的关键字。

解决方案是改用 setFixedSize,这将确保布局在收到有关新的固定大小的通知(不是 当你使用 resize).

时会发生
class ImageWidget(QWidget):
    def __init__(自我):
        超级().__init__()

        self.scale_factor = 1.0
        self.label = QLabel()
        # 不需要这个
        # self.label.setAlignment(Qt.AlignCenter)
        # 不要这样做
        # self.label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)

        self.label.setPixmap(QPixmap("image.png")) # 加载本地测试图像
        self.label.setScaledContents(真)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.label, <b>alignment=Qt.AlignCenter</b>)
        self.setLayout(self.layout)

    # ...

    def resizeUsingScaleFactor(自我):
        self.label.<b>setFixedSize</b>(self.getImageSize() * self.scale_factor)