Reputation: 179
I'm writing a program which has two windows and I want to send a QPixmap image from the first window to the second window. The first window contains one QGraphicsView (FirstView) and one label(Second_View_label) where both will be set to the same image. If the user clicks confirm button the image in the Second_View_label should be sent to the second window and set to the label exist in the second window which is (Third_View_label). My problem is that the image did not present in the Third_View_label.
The code is as follows:
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_())
Can someone tell me what I'm doing wrong!! Thanks.
Upvotes: 0
Views: 225
Reputation: 48231
There are several issues in your code, I'll try to address them as better as possible.
First of all: NEVER write your code using the pyuic
output from a Qt Designer file.
What the pyuic
utility generates should always be used as an imported module, and it should never be edited, nor used as a starting point for your program. Consider it as a resource file (as an image, or json data); see the documentation about this.
There are multiple reasons for this, the most important is that whenever you edit the ui
file you created on Designer you'll have to merge your code with the one from the new generated py
file, which will probably result in some unexpected result or, in most cases, headaches that comes from discrepancies between the logic code you wrote and the modifications you did onto the GUI.
You are connecting the Changed_view_2
signal against an object that will be deleted as soon as the Open_Second_Window
function returns:
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()
You are connecting to a signal that has already been emitted, so it will never be received.
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)
The easiest solution is to create the Second_Window
within __init__
and connect the Changed_view_2
signal to its set_image_view
method right there.
Then, after the ConfirmButton
is clicked, it will correctly hide the current window, which will show the second one with the the image (that has been already set after the Changed_view_2
signal is emitted):
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()
Upvotes: 1