微信公众号:OpenCV开发者联盟
关注获取更多计算机视觉与深度学习知识
引言
PyQT5支持的鼠标信号
mouseMoveEvent
mousePressEvent
mouseReleaseEvent
mouseDoubleClickEvent
其中如果想要捕获鼠标移动(MouseMove)事件必须设置
setMouseTracking(True)
才可以实现支持。一个简单鼠标绘制通常包括三个鼠标事件的处理,分别是:
mousePressEvent鼠标按下 为开始绘制
mouseMoveEvent 鼠标移动 绘制中
mouseReleaseEvent 鼠标释放 结束绘制
def mousePressEvent(self, event):
def mouseMoveEvent(self, event):
def mouseReleaseEvent(self, event):
综合代码演示
1class ImageCanvas(QtWidgets.QWidget):
2 def __init__(self):
3 super().__init__()
4 self.pts = []
5 self.temp_pts = []
6 self.start_x = -1
7 self.start_y = -1
8 self.pressed = False
9 self.line_width = 5
10
11 # monitor key and mouse event...
12 self.setMouseTracking(True)
13
14 # 添加菜单
15 self.save_5_action = QtWidgets.QAction("线宽2", self)
16 self.save_10_action = QtWidgets.QAction("线宽4", self)
17 self.save_15_action = QtWidgets.QAction("线宽8", self)
18 self.clear_action = QtWidgets.QAction("清除", self)
19
20 self.save_5_action.triggered.connect(self.on_save_5)
21 self.save_10_action.triggered.connect(self.on_save_10)
22 self.save_15_action.triggered.connect(self.on_save_15)
23 self.clear_action.triggered.connect(self.clear_canvas)
24
25 self.addAction(self.save_5_action)
26 self.addAction(self.save_10_action)
27 self.addAction(self.save_15_action)
28 self.addAction(self.clear_action)
29
30 # 0 - 圆形, 1 - 矩形, 2 - 直线, 3 - free-style
31 self.draw_type = 0
32 self.circle = [0, 0, 0]
33 self.box = [0, 0, 0, 0]
34 self.line = [0, 0, 0, 0]
35 # trick settings here!!!
36 self.setContextMenuPolicy(2)
37
38 def clear_canvas(self):
39 self.pts.clear()
40 self.temp_pts.clear()
41 self.circle = [0, 0, 0]
42 self.box = [0, 0, 0, 0]
43 self.line = [0, 0, 0, 0]
44 self.repaint()
45
46 def on_save_5(self, s):
47 print(s)
48 self.line_width = 2
49
50 def on_save_10(self, s):
51 print(s)
52 self.line_width = 4
53
54 def on_save_15(self, s):
55 print(s)
56 self.line_width = 8
57
58 def query_draw_type(self):
59 if rbtn1.isChecked():
60 self.draw_type = 0
61 if rbtn2.isChecked():
62 self.draw_type = 1
63 if rbtn3.isChecked():
64 self.draw_type = 2
65 if rbtn4.isChecked():
66 self.draw_type = 3
67
68 def mousePressEvent(self, event):
69 self.query_draw_type()
70 self.pressed = True
71 self.start_x = event.x()
72 self.start_y = event.y()
73 if self.draw_type == 0:
74 self.circle = [self.start_x, self.start_y, 0]
75 if self.draw_type == 1:
76 self.box = [self.start_x, self.start_y, 0, 0]
77 if self.draw_type == 2:
78 self.line = [self.start_x, self.start_y, 0, 0]
79 if self.draw_type == 3:
80 self.temp_pts.clear()
81 self.temp_pts.append((self.start_x, self.start_y))
82
83 def mouseMoveEvent(self, event):
84 if self.pressed and self.start_x > 0 and self.start_y > 0:
85 x = event.x()
86 y = event.y()
87 dx = x - self.start_x
88 dy = y - self.start_y
89 if self.draw_type == 0 and dx > 0 and dy > 0:
90 r = int(np.sqrt(dx*dx + dy*dy))
91 self.circle = [self.start_x, self.start_y, r]
92 if self.draw_type == 1 and dx > 0 and dy > 0:
93 self.box = [self.start_x, self.start_y, dx, dy]
94 if self.draw_type == 2 and abs(dx) > 0 and abs(dy) > 0:
95 self.line = [self.start_x, self.start_y, x, y]
96 if self.draw_type == 3:
97 self.temp_pts.append((x, y))
98 self.repaint()
99
100 def mouseReleaseEvent(self, event):
101 x = event.x()
102 y = event.y()
103 dx = x - self.start_x
104 dy = y - self.start_y
105 if self.draw_type == 0 and dx > 0 and dy > 0:
106 r = int(np.sqrt(dx * dx + dy * dy))
107 self.circle = [self.start_x, self.start_y, r]
108 if self.draw_type == 1 and dx > 0 and dy > 0:
109 self.box = [self.start_x, self.start_y, dx, dy]
110 if self.draw_type == 2 and abs(dx) > 0 and abs(dy) > 0:
111 self.line = [self.start_x, self.start_y, x, y]
112 if self.draw_type == 3:
113 self.temp_pts.append((x, y))
114 self.pts.append(np.copy(self.temp_pts))
115 self.pressed = False
116 self.temp_pts.clear()
117 self.repaint()
118
119 def paintEvent(self, event):
120 painter = QtGui.QPainter(self)
121 painter.fillRect(self.rect(), QtCore.Qt.black)
122 pen = QtGui.QPen(QtCore.Qt.green, 5, QtCore.Qt.DashLine)
123 painter.setPen(pen)
124 font = QtGui.QFont()
125 font.setBold(True)
126 font.setPointSizeF(16)
127 painter.setFont(font)
128 painter.drawText(QtCore.QPoint(5, 25), "OpenCV开发者联盟")
129
130 pen = QtGui.QPen(QtCore.Qt.green, self.line_width)
131 painter.setPen(pen)
132 painter.drawRect(QtCore.QRect(self.box[0], self.box[1], self.box[2], self.box[3]))
133
134 pen = QtGui.QPen(QtCore.Qt.blue, self.line_width)
135 painter.setPen(pen)
136 cx, cy, r = self.circle
137 painter.drawEllipse(QtCore.QRect(cx-r, cy-r, 2*r, 2*r))
138
139 pen = QtGui.QPen(QtCore.Qt.yellow, self.line_width)
140 painter.setPen(pen)
141 painter.drawLine(self.line[0], self.line[1], self.line[2], self.line[3])
142
143 # 5表示线宽
144 pen = QtGui.QPen(QtCore.Qt.red, self.line_width, QtCore.Qt.DashLine)
145 painter.setPen(pen)
146 for c in range(0, len(self.pts), 1):
147 one_contours = self.pts[c]
148 for i in range(0, len(one_contours)-1, 1):
149 x1 = one_contours[i][0]
150 y1 = one_contours[i][1]
151 x2 = one_contours[i+1][0]
152 y2 = one_contours[i+1][1]
153 painter.drawLine(x1, y1, x2, y2)
154
155 for i in range(0, len(self.temp_pts) - 1, 1):
156 x1 = self.temp_pts[i][0]
157 y1 = self.temp_pts[i][1]
158 x2 = self.temp_pts[i + 1][0]
159 y2 = self.temp_pts[i + 1][1]
160 painter.drawLine(x1, y1, x2, y2)
扫码关注
OpenCV开发者联盟,
专注各种语言的OpenCV开发教程分享
OpenCV周边开发技术应用!
扫码查看OpenCV+OpenVIO+Pytorch系统化学习路线图
推荐阅读
CV全栈开发者说 - 从传统算法到深度学习怎么修炼
2022入坑深度学习,我选择Pytorch框架!
Pytorch轻松实现经典视觉任务
教程推荐 | Pytorch框架CV开发-从入门到实战
OpenCV4 C++学习 必备基础语法知识三
OpenCV4 C++学习 必备基础语法知识二
OpenCV4.5.4 人脸检测+五点landmark新功能测试
OpenCV4.5.4人脸识别详解与代码演示
OpenCV二值图象分析之Blob分析找圆
OpenCV4.5.x DNN + YOLOv5 C++推理
OpenCV4.5.4 直接支持YOLOv5 6.1版本模型推理
OpenVINO2021.4+YOLOX目标检测模型部署测试
比YOLOv5还厉害的YOLOX来了,官方支持OpenVINO推理