在调整窗口大小的同时保持 QLabel 中图像的纵横比

假设我有这样的布局:

在调整窗口大小的同时保持 QLabel 中图像的纵横比

我希望左侧对象和右侧对象的比例始终是这样的:

在调整窗口大小的同时保持 QLabel 中图像的纵横比

这样我就可以在左上角添加一个不会太大或太小的小图像,但总是与窗口大小有很好的关系。我怎样才能做到这一点,无论是在设计器中还是在代码中?

我已经发现您似乎可以通过选择布局并将 LayoutStretch 更改为 1,3 之类的内容来执行此操作 - 这在设计器中有效,但是,当我在代码中插入我的图像时,它不尊重它并再次使布局脱离了proption。

我添加了一个担架并使用 QLabel 来显示图像,然后通过 self.LogoLabel.setPixmap(QtGui.QPixmap('res/image.png')) 添加了文件,所以我不明白我需要更改什么才能使图像始终美观且小巧在左上角。

一个测试示例,以防问题不够清楚 - 我需要的图像是 1000x710px 大。

from PyQt5 import QtCore,QtWidgets,QtGui
import sys

class Ui_zebra(object):

    def setupUi(self,zebra):
        zebra.setobjectname("zebra")
        zebra.resize(315,134)
        self.centralwidget = QtWidgets.QWidget(zebra)
        self.centralwidget.setobjectname("centralwidget")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_4.setobjectname("verticalLayout_4")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setContentsMargins(-1,-1,0)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setobjectname("horizontalLayout")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setobjectname("verticalLayout_3")
        self.LogoLabel = QtWidgets.QLabel(self.centralwidget)
        self.LogoLabel.setText("")
        self.LogoLabel.setScaledContents(True)
        self.LogoLabel.setobjectname("LogoLabel")
        self.verticalLayout_3.addWidget(self.LogoLabel)
        spacerItem = QtWidgets.QSpacerItem(20,40,QtWidgets.QSizePolicy.Minimum,QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_3.addItem(spacerItem)
        self.ComboBox_InputType = QtWidgets.QComboBox(self.centralwidget)
        self.ComboBox_InputType.setobjectname("ComboBox_InputType")
        self.ComboBox_InputType.addItem("")
        self.ComboBox_InputType.addItem("")
        self.ComboBox_InputType.addItem("")
        self.ComboBox_InputType.addItem("")
        self.verticalLayout_3.addWidget(self.ComboBox_InputType)
        self.horizontalLayout.addLayout(self.verticalLayout_3)
        self.TextInput_Devices = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.TextInput_Devices.setobjectname("TextInput_Devices")
        self.horizontalLayout.addWidget(self.TextInput_Devices)
        self.horizontalLayout.setStretch(0,1)
        self.horizontalLayout.setStretch(1,3)
        self.verticalLayout_4.addLayout(self.horizontalLayout)
        zebra.setCentralWidget(self.centralwidget)
        self.menuBar_EnterToken = QtWidgets.Qaction(zebra)
        self.menuBar_EnterToken.setobjectname("menuBar_EnterToken")
        self.menuBar_TestToken = QtWidgets.Qaction(zebra)
        self.menuBar_TestToken.setobjectname("menuBar_TestToken")
        self.menuBar_About = QtWidgets.Qaction(zebra)
        self.menuBar_About.setobjectname("menuBar_About")

        self.retranslateUi(zebra)
        QtCore.QMetaObject.connectSlotsByName(zebra)

    def retranslateUi(self,zebra):
        _translate = QtCore.QCoreApplication.translate
        zebra.setWindowTitle(_translate("zebra","zebra"))
        self.ComboBox_InputType.setItemText(0,_translate("zebra","ip"))
        self.ComboBox_InputType.setItemText(1,"Use all devices"))
        self.ComboBox_InputType.setItemText(2,"displayName"))
        self.ComboBox_InputType.setItemText(3,"id"))
        self.menuBar_EnterToken.setText(_translate("zebra","Enter accesstoken"))
        self.menuBar_TestToken.setText(_translate("zebra","Test accesstoken"))
        self.menuBar_About.setText(_translate("zebra","About..."))


class Test(QtWidgets.QMainWindow,Ui_zebra):
    def __init__(self,parent=None):
        super(Test,self).__init__(parent)
        self.setupUi(self)
        self.LogoLabel.setPixmap(QtGui.QPixmap('res/image.png'))

def main():
    app = QtWidgets.QApplication(sys.argv)
    form = Test()
    form.show()
    app.exec_()



if __name__ == '__main__':
    main()

编辑:奇怪的是,我找不到关于如何在 QLabel 中使用图像并在更改窗口大小的同时缩放其大小,同时保持纵横比的单个工作示例。这么基础的东西,哪里都找不到?

hxcn2004 回答:在调整窗口大小的同时保持 QLabel 中图像的纵横比

您首先需要更改布局,使其使用对齐而不是扩展间隔来将标签保持在左上角。此外,标签的某些属性需要调整,以便它可以自由调整自身大小。这一切都可以在 Qt Designer 中完成,但您的示例代码也可以像这样手动修复:

self.LogoLabel = QtWidgets.QLabel(self.centralwidget)
self.LogoLabel.setText("")
self.LogoLabel.setObjectName("LogoLabel")

# new stuff
self.LogoLabel.setScaledContents(False)
self.LogoLabel.setMinimumSize(1,1)
self.LogoLabel.setSizePolicy(
    QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding)
self.LogoLabel.setAlignment(QtCore.Qt.AlignTop)
self.verticalLayout_3.setAlignment(QtCore.Qt.AlignTop)

self.verticalLayout_3.addWidget(self.LogoLabel)

然后可以使用事件过滤器处理动态调整大小,如下所示:

class Test(QtWidgets.QMainWindow,Ui_ZEBRA):
    def __init__(self,parent=None):
        super(Test,self).__init__(parent)
        self.setupUi(self)
        self._logo = QtGui.QPixmap('res/image.png')
        self.LogoLabel.setPixmap(self._logo)
        self.LogoLabel.installEventFilter(self)

    def eventFilter(self,widget,event):
        if event.type() == QtCore.QEvent.Resize and widget is self.LogoLabel:
            self.LogoLabel.setPixmap(self._logo.scaled(
                self.LogoLabel.width(),self.LogoLabel.height(),QtCore.Qt.KeepAspectRatio))
            return True
        return super(Test,self).eventFilter(widget,event)
,

要根据需要缩小图像并保持两个元素之间的比例,您需要像这样设置 setScaledContents(True)

from PyQt5 import QtCore,QtGui,QtWidgets


class Ui_MainWindow(object):
    def setupUi(self,MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(559,289)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored,QtWidgets.QSizePolicy.Ignored)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)
        self.label.setScaledContents(True)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setObjectName("comboBox")
        self.verticalLayout.addWidget(self.comboBox)
        self.horizontalLayout.addLayout(self.verticalLayout)
        spacerItem = QtWidgets.QSpacerItem(40,20,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setObjectName("textBrowser")
        self.horizontalLayout.addWidget(self.textBrowser)
        self.horizontalLayout.setStretch(0,1)
        self.horizontalLayout.setStretch(2,3)
        self.verticalLayout_2.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self,MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow","MainWindow"))
        self.label.setText(_translate("MainWindow","TextLabel"))

import sys
class Test(QtWidgets.QMainWindow,Ui_MainWindow):
    def __init__(self,self).__init__(parent)
        self.setupUi(self)
        pixmap = QtGui.QPixmap('res/image.png')
        pixmap = pixmap.scaled(256,128,QtCore.Qt.KeepAspectRatio,QtCore.Qt.SmoothTransformation)
        self.label.setPixmap(pixmap)
        self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)


def main():
    app = QtWidgets.QApplication(sys.argv)
    form = Test()
    form.show()
    app.exec_()



if __name__ == '__main__':
    main()

为了保持纵横比 - 我认为您必须使用包含标签的 Widget 的 resizeEvent,每当事件被触发时,该标签将大小更改为正确的纵横比。

本文链接:https://www.f2er.com/54236.html

大家都在问