setPixmap 导致进程以退出代码 1 完成 [重复]

Posted

技术标签:

【中文标题】setPixmap 导致进程以退出代码 1 完成 [重复]【英文标题】:setPixmap causes process finished with exit code 1 [duplicate] 【发布时间】:2020-01-31 15:03:31 【问题描述】:

我从函数 (find_defects) 返回一个图像。我看到它是一个有效的图像。

我在return 之前使用cv2.imshow 检查图像,这也符合我的预期。但是,当我尝试在使用 PyQt 设计的 GUI 上显示此图像时,我看到此错误:

Process finished with exit code 1

编辑:最小可重现示例:

from PyQt5.QtCore import *
import cv2
from PyQt5.QtWidgets import QLabel, QWidget, QPushButton, QVBoxLayout, QApplication
from PyQt5.QtGui import QPixmap, QImage


class first_GUI(QWidget):
    def __init__(self):
        # super(first_GUI, self).__init__()
        # super().__init__()
        QWidget.__init__(self)
        self.frame_defects = cv2.imread('output.jpg')
        self.label_text = QLabel("Hi")
        self.label_text.setAlignment(Qt.AlignCenter)
        self.label_text.setStyleSheet("color: rgb(0,0,255);font-weight: bold; font-size: 16pt")
        pushButton_show = QPushButton("Show")
        pushButton_show.setMinimumHeight(40)
        pushButton_show.setStyleSheet("font-weight: bold; font-size: 16pt")
        pushButton_show.clicked.connect(self.show_image)
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.label_text)
        vertical_layout.addWidget(pushButton_show)
        self.setLayout(vertical_layout)
        self.setWindowTitle("PyQt5 first GUI")
        self.resize(400, 300)


    def show_image(self):

        if self.frame_defects is not None:
            image = QImage(self.frame_defects, self.frame_defects.shape[1], self.frame_defects.shape[0],
                           QImage.Format_RGB888)  # The image is stored using a 24-bit RGB format (8-8-8).
            self.pixmap2 = QPixmap.fromImage(image)
        self.label.setPixmap(self.pixmap2)

app = QApplication([])
widget = first_GUI()
widget.show()
app.exec_()  

图片:

【问题讨论】:

这张图片很难阅读。请改为复制并粘贴代码 还要在if ...之前添加self.pixmap2 = QPixmap() @Mustafa 请使用@username。将 image = QImage(...) 更改为 h, w, ch = self.frame_defects.shape bytesPerLine = ch * w image = QImage(self.frame_defects.data, w, h, bytesPerLine, QImage.Format_RGB888).rgbSwapped() @Mustafa 或更改为 self.frame_defects = self.frame_defects[:,:,::-1] h, w, ch = self.frame_defects.shape bytesPerLine = ch * w image = QImage(self.frame_defects.data, w, h, bytesPerLine, QImage.Format_RGB888) OpenCV 默认使用 BGR 格式,但 Qt 使用 RGB,所以蓝色会显示为红色,反之亦然,所以必须将 R 与 B 交换。 【参考方案1】:

考虑使用 QGraphicsView 代替标签。

# Create scene
self.image_item = QGraphicsPixmapItem()
scene = QGraphicsScene(self)
scene.addItem(self.image_item)

# Create GraphicView display
self.view = QGraphicsView(scene, self)
image = QImage(self.frame_defects, self.frame_defects.shape[1], self.frame_defects.shape[0], self.frame_defects.shape[1]*3, QImage.Format_RGB888)
self.image_item.setPixmap(QPixmap.fromImage(image))
self.view.fitInView(self.image_item)

还要注意 self.frame_defects 的 dtype 是 'uint8',如果你没有在 QImage 构造函数中指定 bytesperline 参数,它将被转换为 'uint32' 或 'int32'。因此,为了保持图像每行的字节数,我使用了不同的 QImage 构造函数:

QImage(self.frame_defects, self.frame_defects.shape[1], self.frame_defects.shape[0], self.frame_defects.shape[1]*3, QImage.Format_RGB888)

编辑: 我在我的 PyCharm 中尝试了这段代码,它可以工作:

from PyQt5.QtCore import *
import cv2
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class first_GUI(QWidget):
    def __init__(self):
        # super(first_GUI, self).__init__()
        # super().__init__()
        QWidget.__init__(self)
        self.frame_defects = cv2.imread('output.jpg')
        self.image_item = QGraphicsPixmapItem()
        scene = QGraphicsScene(self)
        scene.addItem(self.image_item)
        self.view = QGraphicsView(scene, self)

        pushButton_show = QPushButton("Show")
        pushButton_show.setMinimumHeight(40)
        pushButton_show.setStyleSheet("font-weight: bold; font-size: 16pt")
        pushButton_show.clicked.connect(self.show_image)

        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(self.view)
        vertical_layout.addWidget(pushButton_show)

        self.setLayout(vertical_layout)
        self.setWindowTitle("PyQt5 first GUI")
        self.resize(400, 300)

    def show_image(self):
        image = QImage(self.frame_defects, self.frame_defects.shape[1], self.frame_defects.shape[0], self.frame_defects.shape[1]*3, QImage.Format_RGB888)
        self.image_item.setPixmap(QPixmap.fromImage(image))
        self.view.fitInView(self.image_item)


app = QApplication([])
widget = first_GUI()
widget.show()
app.exec_()

编辑2:

在 QImage 构造函数后添加 image = image.rgbSwapped():

    def show_image(self):
    image = QImage(self.frame_defects, self.frame_defects.shape[1], self.frame_defects.shape[0], self.frame_defects.shape[1]*3, QImage.Format_RGB888)
    image = image.rgbSwapped()
    self.image_item.setPixmap(QPixmap.fromImage(image))
    self.view.fitInView(self.image_item)

【讨论】:

谢谢,但是当我按下按钮时没有任何反应。我根据你的回答更新了代码 尝试从 QMainWindow 而不是 QWidget 派生 first_GUI,如下所示: class first_GUI(QMainWindow): 我试过了,按钮不显示 好的,但是如果问题中的代码还不能正常工作,请不要更改它:) @kalzso 为什么建议将 QWidget 更改为 QMainWindow?我没有看到其中的逻辑。

以上是关于setPixmap 导致进程以退出代码 1 完成 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Jekyll 编译:进程在 Github 上以退出代码 1 完成

Android Studio AVD - 模拟器:进程以退出代码 1 完成

循环向量退出并出现错误进程以退出代码 -1073741819 完成

如何修复错误“进程以退出代码-1073741819(0xC0000005)完成”

进程以退出代码139完成

当 spring-boot 运行时 IntelliJ 进程以退出代码 0 完成