如何解决在调整窗口大小的同时保持 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 中使用图像并在更改窗口大小的同时缩放其大小,同时保持纵横比的单个工作示例。这么基础的东西,哪里都找不到?
解决方法
您首先需要更改布局,使其使用对齐而不是扩展间隔来将标签保持在左上角。此外,标签的某些属性需要调整,以便它可以自由调整自身大小。这一切都可以在 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,每当事件被触发时,该标签将大小更改为正确的纵横比。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。