将Qpixmap从一个窗口发送到另一窗口

问题描述 投票:0回答:1

我正在编写一个具有两个窗口的程序,我想将QPixmap图像从第一个窗口发送到第二个窗口。第一个窗口包含一个QGraphicsView(FirstView)和一个标签(Second_View_label),在这两个标签中将它们设置为同一图像。如果用户单击确认按钮,则应该将Second_View_label中的图像发送到第二个窗口,并将第二个窗口中存在的标签设置为(Third_View_label)。我的问题是图像没有出现在Third_View_label中。

代码如下:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QLabel, QWidget
from PyQt5.QtGui import  QPixmap
import sys    

class First_View(QtWidgets.QGraphicsView):
    Changed_view = QtCore.pyqtSignal(QtGui.QPixmap)

    def __init__(self, parent=None):
        super().__init__(QtWidgets.QGraphicsScene(), parent)      
        self.pixmap_item = self.scene().addPixmap(QtGui.QPixmap())
        self.pixmap_item.setShapeMode(QtWidgets.QGraphicsPixmapItem.BoundingRectShape)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

    def set_image(self, pixmap):
        self.pixmap_item.setPixmap(pixmap)
        self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
        self.setSceneRect(self.scene().sceneRect())
        self.Changed_view.emit(pixmap)

class Ui_MainWindow(QtWidgets.QMainWindow):
    Changed_view_2 = QtCore.pyqtSignal(QtGui.QPixmap)

    def __init__(self):
        super().__init__()        
        self.resize(1270, 800)
        self.setMinimumSize(QtCore.QSize(1270, 800))
        self.setMaximumSize(QtCore.QSize(1270, 800))
        self.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")      
        self.ConfirmButton = QtWidgets.QPushButton(self.centralwidget)
        self.ConfirmButton.setMinimumSize(QtCore.QSize(200, 60))
        self.ConfirmButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setWeight(75)
        self.ConfirmButton.setFont(font)
        self.ConfirmButton.setCheckable(True)
        self.ConfirmButton.setObjectName("ConfirmButton")
        self.ConfirmButton.setEnabled(False)
        self.gridLayout.addWidget(self.ConfirmButton, 1, 3, 1, 1)        
        self.BrowesButton = QtWidgets.QPushButton(self.centralwidget)
        self.BrowesButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BrowesButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setPointSize(11)
        font.setWeight(75)
        self.BrowesButton.setFont(font)
        self.BrowesButton.setCheckable(True)
        self.BrowesButton.setObjectName("BrowesButton")
        self.gridLayout.addWidget(self.BrowesButton, 1, 0, 1, 1)
        self.FirstView = First_View()
        self.FirstView.setMinimumSize(600, 500)
        self.FirstView.setMaximumSize(600, 500)
        self.FirstView.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.FirstView.setFrameShadow(QtWidgets.QFrame.Plain)
        self.gridLayout.addWidget(self.FirstView, 0, 0, 1, 2)        
        self.Second_View_label = QtWidgets.QLabel(self.centralwidget)
        self.Second_View_label.setEnabled(True)
        self.Second_View_label.setMinimumSize(QtCore.QSize(600, 500))
        self.Second_View_label.setMaximumSize(QtCore.QSize(600, 500))
        self.Second_View_label.setFrameShape(QtWidgets.QFrame.Box)
        self.Second_View_label.setFrameShadow(QtWidgets.QFrame.Plain)
        self.Second_View_label.setLineWidth(1)
        self.Second_View_label.setText("")
        self.Second_View_label.setObjectName("Second_View_label")
        self.gridLayout.addWidget(self.Second_View_label, 0, 3, 1, 1)

        self.setCentralWidget(self.centralwidget)
        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

        self.messege =" Hi "
        self.BrowesButton.clicked.connect(self.load_image)
        self.FirstView.Changed_view.connect(self.set_image)
        self.ConfirmButton.clicked.connect(self.Open_Second_Window)



    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        self.ConfirmButton.setText(_translate("MainWindow", "Confirm"))
        self.BrowesButton.setText(_translate("MainWindow", "Browes for Image"))


    def load_image(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select Image", "", "Image Files (*.png *.jpg *jpeg)"
        )
        if fileName:
            pixmap = QtGui.QPixmap(fileName)
            self.FirstView.set_image(pixmap)

    def set_image(self, pixmap1):
        pixmap = pixmap1.scaled(self.Second_View_label.width(), self.Second_View_label.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
        self.Second_View_label.setPixmap(pixmap)
        self.Second_View_label.setAlignment(QtCore.Qt.AlignCenter) 
        self.ConfirmButton.setEnabled(True)
        self.Changed_view_2.emit(pixmap1)


    def Open_Second_Window(self): 
        #self.w = Second_Window(self.messege)
        w = Second_Window()
        self.win = Second_Window()
        self.win.show()
        self.Changed_view_2.connect(w.set_image_view)
        self.hide()



class Second_Window(QtWidgets.QMainWindow):       
    def __init__(self):
        #print (messege)
        super().__init__()  
        self.resize(1270, 800)
        self.setMinimumSize(QtCore.QSize(1270, 800))
        self.setMaximumSize(QtCore.QSize(1270, 800))
        font = QtGui.QFont()
        self.setFont(font)
        self.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")

        self.Third_View_label = QtWidgets.QLabel(self.centralwidget)
        self.Third_View_label.setEnabled(True)
        self.Third_View_label.setGeometry(QtCore.QRect(50, 60, 600, 500))
        self.Third_View_label.setMinimumSize(QtCore.QSize(600, 500))
        self.Third_View_label.setMaximumSize(QtCore.QSize(600, 500))
        self.Third_View_label.setFrameShape(QtWidgets.QFrame.Box)
        self.Third_View_label.setFrameShadow(QtWidgets.QFrame.Plain)
        self.Third_View_label.setLineWidth(1)
        self.Third_View_label.setText("")
        self.Third_View_label.setObjectName("Third_View_label")
        #self.Third_View_label.setPixmap(pixmap1)

        #self.set_image_view (pixmap1)    # ***** set pixmap to Third_View_label

        self.BackButton = QtWidgets.QPushButton(self.centralwidget)
        self.BackButton.setGeometry(QtCore.QRect(690, 180, 200, 60))
        self.BackButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BackButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setPointSize(11)
        self.BackButton.setFont(font)
        self.BackButton.setCheckable(True)
        self.BackButton.setObjectName("BackButton")
        self.setCentralWidget(self.centralwidget)

        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

        self.BackButton.clicked.connect(self.First_Window)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        self.BackButton.setText(_translate("MainWindow", "Back"))

    def set_image_view (self ,pixmap):   #*********The Problem************
        pixmap = pixmap.scaled(self.Third_View_label.width(), self.Third_View_label.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
        self.Third_View_label.setPixmap(pixmap)
        self.Third_View_label.setAlignment(QtCore.Qt.AlignCenter) 

    def First_Window(self):                                             
        self.w = Ui_MainWindow()
        self.w.show()
        self.hide()    


if __name__ == "__main__": 
    app = QtWidgets.QApplication(sys.argv)
    w = Ui_MainWindow()
    w.show()
    sys.exit(app.exec_())

有人可以告诉我我在做什么错!!谢谢。

python python-3.x pyqt pyqt5 qmainwindow
1个回答
0
投票

您的代码中有几个问题,我将尽力更好地解决它们。

首先:NEVER使用Qt Designer文件中的pyuic输出编写代码。

pyuic实用程序生成的内容应始终用作导入的模块,并且应从不进行编辑,也不得用作程序的起点。将其视为resource文件(作为图像或json数据);参见documentation

原因有很多,最重要的是,每当编辑在Designer上创建的ui文件时,都必须将代码与新生成的py文件中的代码合并,在某些意想不到的结果中,或者在大多数情况下,是您所编写的逻辑代码与对GUI所做的修改之间的差异引起的头痛。


您正在将Changed_view_2信号连接到一个对象,该对象将在Open_Second_Window函数返回后立即被删除:

    def Open_Second_Window(self): 
        #self.w = Second_Window(self.messege)
        w = Second_Window() # <-- this window will be deleted at the end
                            # of this function!
        self.win = Second_Window()
        self.win.show()
        # since "w" will be deleted, the signal won't do anything
        self.Changed_view_2.connect(w.set_image_view)
        self.hide()

您正在连接到已经发出的信号,因此它将永远不会被接收。

class Ui_MainWindow(QtWidgets.QMainWindow):
    Changed_view_2 = QtCore.pyqtSignal(QtGui.QPixmap)

    def __init__(self):
        super().__init__()
        # ...
        self.FirstView.Changed_view.connect(self.set_image)
        # the second window doesn't exist yet! You're just connecting the signal
        # to *create* and open it afterwards.
        self.ConfirmButton.clicked.connect(self.Open_Second_Window)


    def set_image(self, pixmap1):
        pixmap = pixmap1.scaled(self.Second_View_label.width(), self.Second_View_label.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
        self.Second_View_label.setPixmap(pixmap)
        self.Second_View_label.setAlignment(QtCore.Qt.AlignCenter) 
        self.ConfirmButton.setEnabled(True)
        # at this point, the second window doesn't exist yet; even assuming that
        # you correctly connect the "Changed_view_2" signal to the
        # "set_image_view" slot of the "self.w" window in your code, there's
        # no "self.w" at this point yet, so no object will receive this signal
        self.Changed_view_2.emit(pixmap1)

固定代码可能的解决方案

最简单的解决方案是在Second_Window中创建__init__,然后将Changed_view_2信号连接到其set_image_view方法。然后,单击ConfirmButton后,它将正确隐藏当前窗口,该窗口将显示带有图像的第二个窗口(在发出Changed_view_2信号后已设置的图像):

class Ui_MainWindow(QtWidgets.QMainWindow):
    Changed_view_2 = QtCore.pyqtSignal(QtGui.QPixmap)

    def __init__(self):
        super().__init__()        
        # ...
        self.win = Second_Window()
        self.Changed_view_2.connect(self.win.set_image_view)

    # ...

    def set_image(self, pixmap1):
        pixmap = pixmap1.scaled(self.Second_View_label.width(), self.Second_View_label.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
        self.Second_View_label.setPixmap(pixmap)
        self.Second_View_label.setAlignment(QtCore.Qt.AlignCenter) 
        self.ConfirmButton.setEnabled(True)
        # at this point "self.win" exists, and its "set_image_view" will correctly
        # process the following signal
        self.Changed_view_2.emit(pixmap1)

    def Open_Second_Window(self): 
        self.win.show()
        self.hide()
© www.soinside.com 2019 - 2024. All rights reserved.