我正在编写一个具有两个窗口的程序,我想将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_())
有人可以告诉我我在做什么错!!谢谢。
您的代码中有几个问题,我将尽力更好地解决它们。
首先: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()