Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在不使用类的情况下自动调整QLabel pixmap的保留比率?_Python_Pyqt_Resize_Qt Designer_Qlabel - Fatal编程技术网

Python 如何在不使用类的情况下自动调整QLabel pixmap的保留比率?

Python 如何在不使用类的情况下自动调整QLabel pixmap的保留比率?,python,pyqt,resize,qt-designer,qlabel,Python,Pyqt,Resize,Qt Designer,Qlabel,我们正在使用PyQt和Qt设计器制作GUI。现在我们需要一个放置在QLabel中的图像(pixmap)在调整窗口大小时能够很好地保持比例 我一直在阅读其他问题/答案,但它们都使用扩展类。由于我们在UI中不断进行更改,并且是使用Qt Creator创建的,.UI和(相应的).py文件是自动生成的,因此,如果我没有错的话,使用类解决方案对我们来说不是一个好的选择,因为我们应该在每次更新UI时手动更改类的名称 在QLAbel中是否有自动调整pixmap大小的选项,以保持比率并避免使用扩展类 谢谢。一种

我们正在使用PyQt和Qt设计器制作GUI。现在我们需要一个放置在QLabel中的图像(pixmap)在调整窗口大小时能够很好地保持比例

我一直在阅读其他问题/答案,但它们都使用扩展类。由于我们在UI中不断进行更改,并且是使用Qt Creator创建的,.UI和(相应的).py文件是自动生成的,因此,如果我没有错的话,使用类解决方案对我们来说不是一个好的选择,因为我们应该在每次更新UI时手动更改类的名称

在QLAbel中是否有自动调整pixmap大小的选项,以保持比率并避免使用扩展类


谢谢。

一种方法是创建QWidget/QLabel子类并重新实现

void QWidget::resizeEvent(QResizeEvent*事件)[虚拟受保护]

此事件处理程序可以在子类中重新实现,以接收在事件参数中传递的小部件调整大小事件。调用resizeEvent()时,小部件已经有了新的几何体。可以通过QResizeEvent::oldSize()访问旧大小

小部件将被擦除,并在处理调整大小事件后立即接收绘制事件。不需要(或应该)在此处理程序中进行绘图

这需要在C++中完成,而不是Pyqt.

完成后,您可以将自定义小部件添加到QtDesigner,如下所示:


为标签设置背景图像:、背景重复:和背景位置QSS属性。您可以通过表单编辑器或在code
QWidget::setStyleSheet
中执行此操作


QSS的一个很好的起点(附示例)

有几种方法可以做到这一点

首先,可以将Qt设计器中的QLabel升级为用python编写的自定义子类。右键单击QLabel并选择“升级到…”,然后为类指定一个名称(例如“ScaledLabel”),并将头文件设置为自定义子类将从中导入的python模块(例如“mylib.classes”)

然后,自定义子类将重新实现
resizeEvent
,如下所示:

class ScaledLabel(QtGui.QLabel):
    def __init__(self, *args, **kwargs):
        QtGui.QLabel.__init__(self)
        self._pixmap = QtGui.QPixmap(self.pixmap())

    def resizeEvent(self, event):
        self.setPixmap(self._pixmap.scaled(
            self.width(), self.height(),
            QtCore.Qt.KeepAspectRatio))
为了使其正常工作,QLabel应该将其大小策略设置为expanding或minimumExpanding,并且最小大小应该设置为一个小的非零值(以便可以缩小图像)

第二种方法避免使用子类,并使用事件过滤器处理调整大小事件:

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        ...
        self._pixmap = QtGui.QPixmap(self.label.pixmap())
        self.label.installEventFilter(self)

    def eventFilter(self, widget, event):
        if (event.type() == QtCore.QEvent.Resize and
            widget is self.label):
            self.label.setPixmap(self._pixmap.scaled(
                self.label.width(), self.label.height(),
                QtCore.Qt.KeepAspectRatio))
            return True
        return QtGui.QMainWindow.eventFilter(self, widget, event)

令人难以置信的是,在七年之后,它仍然几乎是唯一可以找到的工作Python实现;其他人都告诉我们该做什么,但没有人给出实际的代码

尽管如此,它一开始对我来说并不起作用,因为我碰巧在代码中的其他地方生成了pixmap——具体地说,我的pixmap是在一个函数中生成的,该函数只有在单击按钮时才被激活,因此在窗口初始化期间不被激活

在弄清楚@ekhumoro的第二种方法是如何工作的之后,我对其进行了编辑,以适应这种差异。在实践中,我概括了原始代码,也是因为我不喜欢(出于效率原因)它如何向标签添加一个新的_pixmap属性,它似乎只是原始pixmap的一个副本

以下是他的版本;请注意,我还没有完全测试过它,但由于它是我的原始工作代码的较短版本,所以它也应该可以正常工作(不过,欢迎更正):


这是通过将
ScaledContents
属性设置为
False
,将
SizePolicy
设置为
展开
忽略
来实现的。请注意,如果包含图像的标签未设置为中心小部件(
self.setCentralWidget(self.label)
,其中
self
指的是
MainWindow
)。

Dmitry,样式表?具体如何?Laszlo,那么我需要在同一个项目中混合py和cpp文件吗?或者cpp代码直接在QtCreator?@user3061177中编写:您需要将该类用于生成的ui文件,因此是的,您需要在项目中或单独的库中使用该类进行链接(进行一些修改)。好的,还有附带问题。为什么我不能在Python中使用子类?Qt Creator或PyQT有限制吗?@user3061177:老实说,ekhumoro比我更了解这一点。因此,如果我正确设置QS,图片在调整窗口大小时会适当缩放,或者我仍然需要创建一个子类来触发resizeEvent?是的,设置QS就足够了,没有子分类,我在尝试实现这两种解决方案时遇到了问题。一个问题。是否应激活或停用“缩放内容”属性?@user3061177。
scaledContents
属性应设置为false,您需要根据我的回答设置大小策略和最小大小。我可以发布一个有效的演示,但是我的答案中没有太多可以添加的内容。你到底有什么问题?
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Initialize stuff here; mind that no pixmap is added to the label at this point

    def eventFilter(self, widget, event):
        if event.type() == QEvent.Resize and widget is self.label:
            self.label.setPixmap(self.label.pixmap.scaled(self.label.width(), self.label.height(), aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation))
            return True
        return QMainWindow.eventFilter(self, widget, event)

    def apply_pixelmap(self, image):  # This is where the pixmap is added. For simplicity, suppose that you pass a QImage as an argument to this function; however, you can obtain this in any way you like
        pixmap = QPixmap.fromImage(image).scaled(new_w, new_h, aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation)

        self.label.setPixmap(pixmap)
        self.label.pixmap = QPixmap(pixmap)  # I am aware that this line looks like a redundancy, but without it the program does not work; I could not figure out why, so I will gladly listen to anyone who knows it
        self.label.installEventFilter(self)

        return