在布局中居中 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)
我试图将显示 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)