
import sys
from PyQt5.QtCore import QRect
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
# 设置Widget大小以及固定宽高
self.setFixedSize(520, 768)
#定义鼠标形状
self.setCursor(Qt.CrossCursor)
#初始坐标,初始参数
self.x0 = 0
self.y0 = 0
self.x1 = 0
self.y1 = 0
self.open_mouse_flag = True
self.select_roi_flag = True
self.draw_roi_flag = False
self.clear_flag = False
self.rect = QRect()
# 1. 创建整体的布局器
container = QVBoxLayout()
# 2. 设置当前要显示的Widget,从而能够显示这个布局器中的控件
self.setLayout(container)
#按压鼠标,记录x0,y0的值
def mousePressEvent(self, event):
if self.open_mouse_flag:
self.select_roi_flag = True
self.draw_roi_flag = True
self.clear_flag = False
self.x0 = event.x()
self.y0 = event.y()
# 释放⿏标,清除图像
def mouseReleaseEvent(self, event):
self.select_roi_flag = False
self.clear_label()
# 移动⿏标,不断更新x1,y1的值
def mouseMoveEvent(self, event):
if self.select_roi_flag is True:
self.x1 = event.x()
self.y1 = event.y()
if self.draw_roi_flag is True:
self.update()
# 绘制事件,鼠标点击时自动运行,可以加print("123")验证
def paintEvent(self, event):
super().paintEvent(event) # 继承父类的同名方法
painter = QPainter(self)
#画笔特征
painter.setPen(QPen(Qt.red, 10, Qt.SolidLine))
if self.clear_flag is True:
self.x0 = 0
self.y0 = 0
self.x1 = 0
self.y1 = 0
#这里为什么会清楚图画的原因不太清楚,这个画图不是个循环,可能最后又调用了一次绘图?
# print(self.x0,self.y0,self.x1,self.y1)
#使图像绘制起点和鼠标位置保持一致,确保绘制图像与鼠标在同一侧
if self.x1 != 0 and self.y1 != 0:
self.rect = QRect(min(self.x0, self.x1), min(self.y0, self.y1), abs(self.x1 - self.x0), \
abs(self.y1 - self.y0))
#绘图
painter.drawRect(self.rect)
#更新
self.update()
#可以在不同对象之间通过信号传递调用槽,改变open_mouse_flag的值,由于本例较为简单,此函数没有被调用
def change(self):
self.open_mouse_flag = True
#调用此函数则停止绘制,参见61行
def clear_label(self):
self.clear_flag = True
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyWindow()
win.show()
app.exec()