将 Qpixmap 从一个 window 发送到另一个 window
Sending Qpixmap from one window to another window
我正在编写一个有两个 windows 的程序,我想将 QPixmap 图像从第一个 window 发送到第二个 window。第一个 window 包含一个 QGraphicsView (FirstView) 和一个标签 (Second_View_label),其中两者将被设置为相同的图像。如果用户单击确认按钮,Second_View_label 中的图像应发送到第二个 window 并设置为存在于第二个 window 中的标签,即 (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_())
谁能告诉我我做错了什么!!
谢谢
您的代码中存在几个问题,我会尽力解决。
首先:从不 使用 Qt Designer 文件的 pyuic
输出编写代码。
pyuic
实用程序生成的内容应始终用作导入模块,并且 永远不要 对其进行编辑,也不应将其用作程序的起点。将其视为 资源 文件(作为图像,或 json 数据);请参阅有关此的 documentation。
这有多种原因,最重要的是每当您编辑在 Designer 上创建的 ui
文件时,您都必须将您的代码与新生成的 py
文件,这可能会导致一些意想不到的结果,或者在大多数情况下,由于您编写的逻辑代码与您对 GUI 所做的修改之间的差异而令人头疼。
您正在将 Changed_view_2
信号连接到将在 Open_Second_Window
函数 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()
您正在连接到一个已经发出的信号,因此永远不会收到。
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)
固定代码的可能解决方案
最简单的解决方案是在 __init__
中创建 Second_Window
并将 Changed_view_2
信号连接到它的 set_image_view
方法。
然后,点击ConfirmButton
后,会正确隐藏当前的window,会显示第二张图片(已设置) 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()
我正在编写一个有两个 windows 的程序,我想将 QPixmap 图像从第一个 window 发送到第二个 window。第一个 window 包含一个 QGraphicsView (FirstView) 和一个标签 (Second_View_label),其中两者将被设置为相同的图像。如果用户单击确认按钮,Second_View_label 中的图像应发送到第二个 window 并设置为存在于第二个 window 中的标签,即 (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_())
谁能告诉我我做错了什么!! 谢谢
您的代码中存在几个问题,我会尽力解决。
首先:从不 使用 Qt Designer 文件的 pyuic
输出编写代码。
pyuic
实用程序生成的内容应始终用作导入模块,并且 永远不要 对其进行编辑,也不应将其用作程序的起点。将其视为 资源 文件(作为图像,或 json 数据);请参阅有关此的 documentation。
这有多种原因,最重要的是每当您编辑在 Designer 上创建的 ui
文件时,您都必须将您的代码与新生成的 py
文件,这可能会导致一些意想不到的结果,或者在大多数情况下,由于您编写的逻辑代码与您对 GUI 所做的修改之间的差异而令人头疼。
您正在将 Changed_view_2
信号连接到将在 Open_Second_Window
函数 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()
您正在连接到一个已经发出的信号,因此永远不会收到。
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)
固定代码的可能解决方案
最简单的解决方案是在 __init__
中创建 Second_Window
并将 Changed_view_2
信号连接到它的 set_image_view
方法。
然后,点击ConfirmButton
后,会正确隐藏当前的window,会显示第二张图片(已设置) 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()