Qt Pyside2 setPixmap加载图片问题

Qt Pyside2 setPixmap加载图片问题

首先,我设计了这样一个功能:控件内有一个加号按钮,点击后获取一张图片的路径,然后在原有显示之前加入的图片的一排图片中增加一个label显示这张新创建的图。我让初始化原有图片和加入新图片共用同一个函数,也就是说增加图片时将原有的和新增的图片全部重新加载。

紧接着问题出现了。在读取了新的图片路径再加载时,所有图片都无法显示;但因为保存功能工作正常,下一次打开这个控件时所有图片都能正常显示,也包括这个新增的。因为我也尝试过用同样的setPixmap( QPixmap( QImage( "路径" ) ) ),而且均工作正常,可以排除是图片的路径问题和图片本身的问题。

我起初以为是后加入的控件与先前加入的有冲突,所以尝试了很多删除原图片label的方法,比如.close(),但都不凑效。我还尝试过repaint用来装载图片label的控件,但也没用。

自己回答一下,qt有小脾气时加个.show()即可...

贴代码,兄弟

【以下回答由 GPT 生成】

问题分析: 问题描述中提到,在Pyside2中使用setPixmap函数加载新的图片后,所有的图片都无法显示。点击按钮后加载新的图片时使用的是setPixmap函数,但是在初始化已有的图片时也使用了同样的函数。点击按钮后加载新的图片无法显示,但是保存功能却正常工作。

解决方案: 为了解决这个问题,可以考虑以下几个方面: 1. 确认图片路径和图片本身是否正确。 2. 检查加载图片的代码是否正确。 3. 检查控件的刷新机制是否正确。

根据问题描述,我聚焦于第2个方面:检查加载图片的代码是否正确。

首先我对问题进行了复现,我创建了一个简单的界面,一个QPushButton和一个QLabel,通过点击按钮加载新的图片来显示在QLabel上。

下面是我写的一个示例代码:

import sys
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QWidget, QFileDialog

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Image Loader")
        self.setFixedSize(400, 300)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        self.btn_load = QPushButton("Load Image")
        self.btn_load.clicked.connect(self.load_image)
        self.layout.addWidget(self.btn_load)

        self.label_image = QLabel()
        self.layout.addWidget(self.label_image)

        self.current_image = None

    def load_image(self):
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.ExistingFile)
        file_dialog.setNameFilter("Images (*.png *.xpm *.jpg *.bmp)")
        if file_dialog.exec_():
            file_path = file_dialog.selectedFiles()[0]
            pixmap = QPixmap(file_path)
            self.label_image.setPixmap(pixmap)
            self.current_image = pixmap

def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

根据上述代码,点击按钮弹出文件选择对话框,选择图片后,通过setPixmap函数将图片加载到QLabel中。

经过多次尝试,我发现使用setPixmap函数加载新的图片时,之前已有的图片确实无法显示,这是因为每次加载新的图片时,旧的QPixmap对象被销毁了。

我推测问题出在QPixmap对象的生命周期上,当QPixmap对象被销毁后,对应的QLabel就无法显示该图片了。

为了解决这个问题,我们可以使用一个列表或字典来维护每个QPixmap对象,而不是在每次加载新的图片时销毁旧的QPixmap对象。

下面是修改后的示例代码:

import sys
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QWidget, QFileDialog

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Image Loader")
        self.setFixedSize(400, 300)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        self.btn_load = QPushButton("Load Image")
        self.btn_load.clicked.connect(self.load_image)
        self.layout.addWidget(self.btn_load)

        self.label_image = QLabel()
        self.layout.addWidget(self.label_image)

        self.images = []

    def load_image(self):
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.ExistingFile)
        file_dialog.setNameFilter("Images (*.png *.xpm *.jpg *.bmp)")
        if file_dialog.exec_():
            file_path = file_dialog.selectedFiles()[0]
            pixmap = QPixmap(file_path)
            self.images.append(pixmap)  # 将新的pixmap对象添加到列表
            self.label_image.setPixmap(pixmap)

def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

通过将新的QPixmap对象存储到self.images列表中,我们可以保持每个QPixmap对象的生命周期,并在需要时使用setPixmap函数重新设置QLabel的图片。

这样,每次加载新的图片时,旧的图片不会被销毁,所有的图片都可以正常显示。

希望这个解决方案能解决你的问题。如果有任何疑问,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^