目录
1. 主窗口传递到副窗口
2. 互传消息
3. 在副窗口绘制点或者拉框
功能:主窗口传递图像到对话窗口。
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
# 对话窗口
class Dialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.setWindowTitle("Dialog")
self.label = QtWidgets.QLabel(self)
self.label.setFixedSize(300, 300)
self.label.setAlignment(QtCore.Qt.AlignCenter)
def set_image(self, image):
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
# 主窗口:有一个按钮,有一个对话窗口实例,点击此按钮,触发传递图像到窗口实例
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Main Window")
self.button = QtWidgets.QPushButton("Open Dialog", self)
self.button.clicked.connect(self.open_dialog)
self.dialog = Dialog(self) # 窗口实例
def open_dialog(self):
image_path = "path/to/your/image.png" # 替换为你的图像路径
image = QtGui.QImage(image_path)
self.dialog.set_image(image)
self.dialog.exec_()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
升级版:主窗口传递图像到对话窗口,点击图像后,把点击的位置传回到主窗口。
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
# 对话窗口,点击label中的位置,返回到主窗口
class Dialog(QtWidgets.QDialog):
position_clicked = QtCore.pyqtSignal(QtCore.QPoint) # 传递的信号类型:QtCore.QPoint
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.setWindowTitle("Dialog")
self.label = QtWidgets.QLabel(self) # 只有一个label部件
# self.label.setFixedSize(800, 800)
self.label.setAlignment(QtCore.Qt.AlignCenter)
def mousePressEvent(self, event): # 在label部件中点击的坐标
if event.button() == QtCore.Qt.LeftButton:
position = event.pos()
self.position_clicked.emit(position) # 发送信号
def set_image(self, image):
self.label.setFixedSize(image.width(), image.height()) # 图像填满label
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
# 主窗口:只有一个按钮,一个对话窗口实例,点击按钮触发传递图像到实例窗口,并将信号进行关联。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Main Window")
self.button = QtWidgets.QPushButton("Open Dialog", self) # 点击按钮触发传递图像到实例窗口
self.button.clicked.connect(self.open_dialog)
self.dialog = Dialog(self)
self.dialog.position_clicked.connect(self.handle_position) # 信号关联
def open_dialog(self):
image_path = "/home/zxq/Pictures/1.png" # 替换为你的图像路径
image = QtGui.QImage(image_path)
self.dialog.set_image(image)
self.dialog.exec_()
def handle_position(self, position): # 获取传回信号
print("Position clicked:", position.x(), position.y())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
绘制点
import sys
import cv2
from PyQt5 import QtWidgets, QtGui, QtCore
# 自定义的QLabel子类,用于在Label部件上绘制点
class DrawingLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super(DrawingLabel, self).__init__(parent)
self.points = []
def paintEvent(self, event):
super(DrawingLabel, self).paintEvent(event) # 绘制原始图像
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtGui.QPen(QtCore.Qt.red, 5))
for point in self.points:
painter.drawPoint(point)
# 对话窗口,点击label图像中的位置,返回到主窗口
class DotLocDialog(QtWidgets.QDialog):
position_clicked = QtCore.pyqtSignal(QtCore.QPoint) # 传递的信号类型:QtCore.QPoint
def __init__(self, parent=None):
super(DotLocDialog, self).__init__(parent)
self.setWindowTitle("Dialog")
self.label = DrawingLabel(self) # 使用自定义的QLabel子类
self.label.setAlignment(QtCore.Qt.AlignCenter)
def mousePressEvent(self, event): # 在label部件中点击的坐标
if event.button() == QtCore.Qt.LeftButton:
position = event.pos()
self.position_clicked.emit(position) # 发送信号
self.label.points.append(position)
self.label.update() # 刷新绘制
def set_image(self, image):
self.label.setFixedSize(image.width(), image.height()) # 图像填满label
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
self.label.points = [] # 清空绘制的点
# 主窗口:只有一个按钮,一个对话窗口实例,点击按钮触发传递图像到实例窗口,并将信号进行关联。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Main Window")
self.button = QtWidgets.QPushButton("Open Dialog", self) # 点击按钮触发传递图像到实例窗口
self.button.clicked.connect(self.open_dialog)
self.dialog = DotLocDialog(self)
self.dialog.position_clicked.connect(self.handle_position) # 信号关联
def convert_mat_to_qimage(self, mat):
height, width, channels = mat.shape
bytes_per_line = channels * width
qimage = QtGui.QImage(mat.data, width, height, bytes_per_line, QtGui.QImage.Format_RGB888)
qimage = qimage.rgbSwapped()
return qimage
def open_dialog(self):
image_path = "/home/zxq/Pictures/1.png" # 替换为你的图像路径
img = cv2.imread(image_path)
image = self.convert_mat_to_qimage(img)
self.dialog.set_image(image)
self.dialog.exec_()
def handle_position(self, position): # 获取传回信号
print("Position clicked:", position.x(), position.y())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
绘制矩形框
import sys
from PyQt5 import QtWidgets, QtGui, QtCore
class DrawingLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super(DrawingLabel, self).__init__(parent)
self.start_point = None
self.end_point = None
self.rectangles = []
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.start_point = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self.end_point = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.end_point = event.pos()
self.rectangles.append(QtCore.QRect(self.start_point, self.end_point))
self.update()
self.parent().handle_rectangles(self.rectangles)
def paintEvent(self, event):
super(DrawingLabel, self).paintEvent(event)
painter = QtGui.QPainter(self)
painter.setPen(QtGui.QPen(QtCore.Qt.red, 2))
if self.start_point and self.end_point:
rect = QtCore.QRect(self.start_point, self.end_point)
painter.drawRect(rect)
class RegionDialogWindow(QtWidgets.QDialog):
def __init__(self, image, parent=None):
super(RegionDialogWindow, self).__init__(parent)
self.setWindowTitle("Dialog Window")
self.label = DrawingLabel(self)
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
self.setLayout(layout)
def handle_rectangles(self, rectangles):
self.parent().handle_rectangles(rectangles)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Main Window")
self.button = QtWidgets.QPushButton("Open Dialog", self)
self.button.clicked.connect(self.open_dialog)
def open_dialog(self):
image_path = "/home/zxq/Pictures/1.png"
img = QtGui.QImage(image_path)
dialog = RegionDialogWindow(img, self)
dialog.show()
def handle_rectangles(self, rectangles):
print("\n")
for rect in rectangles:
print("Rectangle:", rect.x(), rect.y(), rect.width(), rect.height())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
绘制直线。
import sys
import cv2
from PyQt5 import QtWidgets, QtGui, QtCore
class DrawingLabel(QtWidgets.QLabel):
def __init__(self, parent=None):
super(DrawingLabel, self).__init__(parent)
self.start_point = None
self.end_point = None
self.two_pt_dis_list = []
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.start_point = event.pos()
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
self.end_point = event.pos()
self.update()
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.end_point = event.pos()
self.two_pt_dis_list.append([self.start_point, self.end_point])
self.update()
self.parent().handle_two_pts(self.two_pt_dis_list)
def paintEvent(self, event):
super(DrawingLabel, self).paintEvent(event)
painter = QtGui.QPainter(self)
painter.setPen(QtGui.QPen(QtCore.Qt.red, 2))
if self.start_point and self.end_point:
painter.drawLine(self.start_point, self.end_point)
class TwoPtsHeightDialogWindow(QtWidgets.QDialog):
def __init__(self, image, parent=None):
super(TwoPtsHeightDialogWindow, self).__init__(parent)
self.setWindowTitle("Dialog Window")
self.label = DrawingLabel(self)
self.label.setPixmap(QtGui.QPixmap.fromImage(image))
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
self.setLayout(layout)
def handle_two_pts(self, rectangles):
self.parent().handle_two_pts(rectangles)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Main Window")
self.button = QtWidgets.QPushButton("Open Dialog", self)
self.button.clicked.connect(self.open_dialog)
def open_dialog(self):
image_path = "/home/zxq/Pictures/1.png"
self.cv_img = cv2.imread(image_path)
image = self.convert_mat_to_qimage(self.cv_img)
dialog = TwoPtsHeightDialogWindow(image, self)
dialog.show()
def convert_mat_to_qimage(self, mat):
height, width, channels = mat.shape
bytes_per_line = channels * width
qimage = QtGui.QImage(mat.data, width, height, bytes_per_line, QtGui.QImage.Format_RGB888)
qimage = qimage.rgbSwapped()
return qimage
def handle_two_pts(self, two_pts_list):
print("\n")
for two_pts in two_pts_list:
print(two_pts)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())