Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.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 我怎样才能拥有一个与它所显示的QPixmap大小完全相同的QLabel?_Python_Pyqt_Qlabel_Qlayout - Fatal编程技术网

Python 我怎样才能拥有一个与它所显示的QPixmap大小完全相同的QLabel?

Python 我怎样才能拥有一个与它所显示的QPixmap大小完全相同的QLabel?,python,pyqt,qlabel,qlayout,Python,Pyqt,Qlabel,Qlayout,我需要一些关于QT/PyQt布局的建议 我想要实现的是让图像正确显示、居中、缩放,在保持纵横比的同时尽可能占据最大的空间。这可以通过以下方式轻松完成: class Demo(QWidget): def __init__(self) -> None: super().__init__() self.setWindowState(Qt.WindowMaximized) self.layout = QVBoxLayout()

我需要一些关于QT/PyQt布局的建议

我想要实现的是让图像正确显示、居中、缩放,在保持纵横比的同时尽可能占据最大的空间。这可以通过以下方式轻松完成:

class Demo(QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.setWindowState(Qt.WindowMaximized)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.button = QPushButton("Next image")
        self.label = QLabel()
        self.label.setStyleSheet("QLabel { background-color : red; }")
        self.label.setAlignment(Qt.AlignCenter)

        self.layout.addWidget(self.label)
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.showImage)
        self.show()


    def showImage(self):
        self.pixmap = QPixmap("image.jpg")
        scaled = self.pixmap.scaled(self.label.size(), Qt.KeepAspectRatio)
        self.label.setPixmap(scaled)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Demo()
    sys.exit(app.exec_())
问题是,图像将以标签为中心显示,周围有很多多余的标签参见屏幕截图,红色部分

但我需要的标签是准确的图像大小。我想在图像上进行一些橡皮粘贴,以选择其中的一部分选择框供以后在retinanet培训中使用,并计算映射到全局和映射到全局所需的框的正确大小。我无法从Pixmap本身执行此操作,因为它不是小部件,当我从标签执行此操作时,会得到错误的值,因为它比实际图像大

现在,我可以使用GridLayout或带有间隔项的HBoxLayout。问题在于逻辑。当UI加载时,标签和项目的大小将确定。当我稍后动态添加一个图像时,它会缩放到标签的大小,即使它可能更大,如果只有间隔项会让位于标签。结果是,并没有太多的左右标签,而是有太多的顶部和底部标签。我希望你明白我的意思

我现在做的是:

根据屏幕分辨率调整窗口大小 添加缩放图像 调整大小0,0 然后调整应用程序的大小,使标签正好是我想要的图像大小,但这是一种邪恶的、黑客的、闪烁的、疯狂的方式-

编辑: 非常感谢你的回答,@eyllanesc:- 我试过了,它符合我第一张照片的要求。我忘了提到的是,当第一个图像正确地用橡胶粘合时,单击“下一步”按钮后,会显示另一个图像。如果此图像小于实际标签或横向而不是纵向,则标签会缩小。瞧,在一些不同分辨率和方向的图像之后,标签不断缩小


一种可能的解决方案是将水平策略size更改为QSizePolicy::max,并将小部件置于布局的中心:

from PyQt5 import QtCore, QtGui, QtWidgets

class Demo(QtWidgets.QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.setWindowState(QtCore.Qt.WindowMaximized)
        layout = QtWidgets.QVBoxLayout(self)
        self.button = QtWidgets.QPushButton("Next image")
        self.label = QtWidgets.QLabel()
        self.label.setStyleSheet("QLabel { background-color : red; }")
        layout.addWidget(self.label)
        layout.addWidget(self.button)
        self.button.clicked.connect(self.showImage)
        self.show()

    def showImage(self):
        self.pixmap = QtGui.QPixmap("image.jpg")
        scaled = self.pixmap.scaled(self.label.size(), QtCore.Qt.KeepAspectRatio)
        self.label.setPixmap(scaled)
        sp = self.label.sizePolicy()
        sp.setHorizontalPolicy(QtWidgets.QSizePolicy.Maximum)
        self.label.setSizePolicy(sp)
        self.layout().setAlignment(self.label, QtCore.Qt.AlignCenter)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ex = Demo()
    sys.exit(app.exec_())
更新:

以前的解决方案的问题是,以前的QLabel的大小被用作建立新大小的参考,而应该基于它可能具有的最大大小,为此,我实现了一个跟踪最大大小的自定义类:

from PyQt5 import QtCore, QtGui, QtWidgets
from itertools import cycle
from glob import glob

class Label(QtWidgets.QLabel):
    def resizeEvent(self, event):
        if not hasattr(self, 'maximum_size'):
            self.maximum_size = self.size()
        else:
            self.maximum_size = QtCore.QSize(
                max(self.maximum_size.width(), self.width()),
                max(self.maximum_size.height(), self.height()),
            )
        super(Label, self).resizeEvent(event)

    def setPixmap(self, pixmap):
        scaled = pixmap.scaled(self.maximum_size, QtCore.Qt.KeepAspectRatio)
        super(Label, self).setPixmap(scaled)

class Demo(QtWidgets.QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.setWindowState(QtCore.Qt.WindowMaximized)
        layout = QtWidgets.QVBoxLayout(self)
        self.button = QtWidgets.QPushButton("Next image")
        self.label = Label()
        self.label.setStyleSheet("QLabel { background-color : red; }")
        layout.addWidget(self.label)
        layout.addWidget(self.button)
        self.button.clicked.connect(self.showImage)
        self.show() 
        self.images = cycle(glob("images/*"))

    def showImage(self):
        try:
            filename = next(self.images)
            self.label.setPixmap(QtGui.QPixmap(filename))
            sp = self.label.sizePolicy()
            sp.setHorizontalPolicy(QtWidgets.QSizePolicy.Maximum)
            self.label.setSizePolicy(sp)
            self.layout().setAlignment(self.label, QtCore.Qt.AlignCenter)
        except StopIteration:
            pass

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ex = Demo()
    sys.exit(app.exec_())

非常感谢你的回答:-我试过了,它符合我第一张照片的要求。我忘了提到的是,当第一个图像正确地用橡胶粘合时,单击“下一步”按钮后,会显示另一个图像。如果此图像小于实际标签或横向而不是纵向,则标签会缩小。你看,在一些不同分辨率和方向的图像之后,标签不断缩小…这是用你的代码从上面拍摄的,同样的两个图像一遍又一遍。我想有在全屏和图像缩放到最大可能的大小,同时保持纵横比的应用程序。那样的话,我发现橡胶粘合是最简单的。。。它不需要被最大化,固定缩放到屏幕分辨率将是一个很好的作品像一个魅力!万分感谢:-