def textToImg(self, plaintext): text = base64.b64encode(str(plaintext).encode("utf-8")) #text = str(plaintext).encode("utf-8") length = len(text) m = hashlib.sha256() m.update(text) texthash = m.hexdigest() qrsize = 500 div = length / qrsize modulus = length % qrsize if modulus > 0: div = div + 1 # clear layout while not self.qrbox.isEmpty(): item = self.qrbox.itemAt(0) item.widget().setParent(None) #self.pic.setPixmap(QtGui.QPixmap.fromImage(imq)) #self.pic.adjustSize() pic = [] for p in range(div): im = self.makeQRCode('bearcode:%s[%dof%d] %s' % (texthash, p + 1, div, text[p * qrsize:min(( (p + 1) * qrsize), length)])) #imq = ImageQt(im.resize((im.size[0]/1, im.size[1]/1), Image.ANTIALIAS).convert("RGBA")) imq = ImageQt(im.convert("RGBA")) painter = QtGui.QPainter(imq) imqrect = imq.rect() painter.setFont(QtGui.QFont("Arial", 24)) rect = painter.boundingRect(imqrect, 0x84, "%d of %d" % (p + 1, div)) painter.fillRect(rect, QtGui.QColor(255, 255, 255)) painter.drawText(imqrect, 0x84, "%d of %d" % (p + 1, div)) del painter thispic = QtGui.QLabel() thispic.setPixmap(QtGui.QPixmap.fromImage(imq)) thispic.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.qrbox.addWidget(thispic) pic.append(thispic)
def textToImg(self, plaintext): text = base64.b64encode(str(plaintext).encode("utf-8")) #text = str(plaintext).encode("utf-8") length = len(text) m = hashlib.sha256() m.update(text) texthash = m.hexdigest() qrsize = 500 div = length/qrsize modulus = length%qrsize if modulus > 0: div = div + 1 # clear layout while not self.qrbox.isEmpty(): item = self.qrbox.itemAt(0) item.widget().setParent(None) #self.pic.setPixmap(QtGui.QPixmap.fromImage(imq)) #self.pic.adjustSize() pic = [] for p in range(div): im = self.makeQRCode('bearcode:%s[%dof%d] %s' % (texthash, p+1, div, text[p*qrsize:min(((p+1)*qrsize),length)])) #imq = ImageQt(im.resize((im.size[0]/1, im.size[1]/1), Image.ANTIALIAS).convert("RGBA")) imq = ImageQt(im.convert("RGBA")) painter = QtGui.QPainter(imq) imqrect = imq.rect() painter.setFont(QtGui.QFont("Arial", 24)) rect = painter.boundingRect(imqrect, 0x84, "%d of %d" % (p+1, div)) painter.fillRect(rect, QtGui.QColor(255,255,255)) painter.drawText(imqrect, 0x84, "%d of %d" % (p+1, div)) del painter thispic = QtGui.QLabel() thispic.setPixmap(QtGui.QPixmap.fromImage(imq)) thispic.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.qrbox.addWidget(thispic) pic.append(thispic)
class ModelViewerWindow(Ui_MainWindow): def __init__(self): super(ModelViewerWindow, self).__init__() self.imgQ = None self.model = None self.input_sliders = [] def setup(self): self.actionQuit.triggered.connect(self.action_quit_triggered) self.actionRandomize.triggered.connect(self.action_randomize_triggered) self.actionReset.triggered.connect(self.action_reset_triggered) # self.graphicsView self.scene = QGraphicsScene() rect = self.graphicsView.rect() print(rect) print(self.graphicsView.frameRect()) self.scene.setSceneRect(QRectF(rect)) self.graphicsView.setScene(self.scene) def action_quit_triggered(self): sys.exit(0) def displayImage(self, img): self.scene.clear() w, h = img.size self.imgQ = ImageQt( img) # we need to hold reference to imgQ, or it will crash pixMap = QPixmap.fromImage(self.imgQ) self.scene.addPixmap(pixMap) self.fixImageSize() self.scene.update() def fixImageSize(self): if self.imgQ: rectf = QRectF(self.imgQ.rect()) self.scene.setSceneRect(rectf) self.graphicsView.fitInView(rectf, Qt.KeepAspectRatio) def resizeEvent(self, e): # print(self.imgQ.rect()) # rectf = QRectF(self.scene.sceneRect()) self.fixImageSize() super().resizeEvent(e) def load_model(self, model_path, model_weights_path=None): if model_weights_path: print("loading model from json:", model_path) with open(model_path) as f: self.model = model_from_json("".join(f.readlines())) print("loading weights from", model_weights_path) self.model.load_weights(str(model_weights_path)) else: print("loading full model:", model_path) self.model = load_model(str(model_path)) self.update_gui_for_model() def update_gui_for_model(self): self.input_sliders = [] for input_layer in self.model.inputs: print(input_layer) print(input_layer.get_shape()) grpInputTemplate = QGroupBox(self.scrInputsContents) grpInputTemplate.setObjectName("grpInputTemplate") verticalLayout_2 = QVBoxLayout(grpInputTemplate) verticalLayout_2.setContentsMargins(0, 0, 0, 0) verticalLayout_2.setSpacing(0) verticalLayout_2.setObjectName("verticalLayout_2") lblInputName = QLabel(grpInputTemplate) lblInputName.setText(input_layer.name) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( lblInputName.sizePolicy().hasHeightForWidth()) lblInputName.setSizePolicy(sizePolicy) lblInputName.setMinimumSize(QSize(20, 0)) lblInputName.setAlignment(Qt.AlignCenter) lblInputName.setObjectName("lblInputName_{}".format( input_layer.name)) layer_sliders = [] for feature in range(input_layer.get_shape()[1]): frFeatureTemplate = QFrame(grpInputTemplate) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( frFeatureTemplate.sizePolicy().hasHeightForWidth()) frFeatureTemplate.setSizePolicy(sizePolicy) frFeatureTemplate.setFrameShape(QFrame.StyledPanel) frFeatureTemplate.setFrameShadow(QFrame.Raised) frFeatureTemplate.setObjectName("frInputFeature_{}_{}".format( input_layer.name, feature)) horizontalLayout = QHBoxLayout(frFeatureTemplate) horizontalLayout.setObjectName("horizontalLayout") lblFeatureIndex = QLabel(frFeatureTemplate) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( lblFeatureIndex.sizePolicy().hasHeightForWidth()) lblFeatureIndex.setSizePolicy(sizePolicy) lblFeatureIndex.setMinimumSize(QSize(20, 0)) lblFeatureIndex.setAlignment(Qt.AlignCenter) lblFeatureIndex.setObjectName("lblFeatureIndex_{}_{}".format( input_layer.name, feature)) lblFeatureIndex.setText(str(feature)) horizontalLayout.addWidget(lblFeatureIndex) sliderFeatureValue = SliderFeature(frFeatureTemplate) sliderFeatureValue.setMinimumSize(QSize(100, 0)) sliderFeatureValue.setOrientation(Qt.Horizontal) sliderFeatureValue.setMinimum(-1000) sliderFeatureValue.setMaximum(1000) sliderFeatureValue.setObjectName( "sliderFeatureValue_{}_{}".format(input_layer.name, feature)) sliderFeatureValue.valueChanged.connect( self.sliderFeatureValue_onValueChanged) sliderFeatureValue.sliderReleased.connect( self.sliderFeatureValue_onSliderReleased) horizontalLayout.addWidget(sliderFeatureValue) layer_sliders.append(sliderFeatureValue) lblFeatureValue = QLabel(frFeatureTemplate) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( lblFeatureValue.sizePolicy().hasHeightForWidth()) lblFeatureValue.setSizePolicy(sizePolicy) lblFeatureValue.setMinimumSize(QSize(40, 0)) lblFeatureValue.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter) lblFeatureValue.setObjectName("lblFeatureValue_{}_{}".format( input_layer.name, feature)) lblFeatureValue.setText("0") horizontalLayout.addWidget(lblFeatureValue) verticalLayout_2.addWidget(frFeatureTemplate) self.vertInputs.addWidget(grpInputTemplate) self.input_sliders.append(layer_sliders) def sliderFeatureValue_onValueChanged(self, value): # print(type(self), self, type(value), value) for layer_sliders in self.input_sliders: for slider in layer_sliders: label = slider.parent().findChildren( QLabel, slider.objectName().replace("slider", "lbl"))[0] label.setText(str(slider.value() / 1000)) def sliderFeatureValue_onSliderReleased(self): self.updateOutput() def updateOutput(self): inputs = [ np.asarray([slider.value() / 1000 for slider in layer_sliders ]).reshape(-1, len(layer_sliders)) for layer_sliders in self.input_sliders ] print(inputs) self.renderInputs(inputs) def renderInputs(self, inputs): array = self.model.predict(inputs)[0] img = array_to_img(array) self.displayImage(img) def action_randomize_triggered(self): print("randomize inputs") for layer_sliders in self.input_sliders: for slider in layer_sliders: slider.setValue( random.randint(slider.minimum(), slider.maximum())) self.updateOutput() def action_reset_triggered(self): print("reset inputs") for layer_sliders in self.input_sliders: for slider in layer_sliders: slider.setValue(0) self.updateOutput()
class DataCleanerWindow(Ui_MainWindow): """docstring for DataCleanerWindow.""" def __init__(self): super(DataCleanerWindow, self).__init__() # self._mainWindow = QMainWindow() self.setupUi() self.raw_image_path = Path("data/raw") self.good_image_path = Path("data/good/img") self.bad_image_path = Path("data/bad/img") if not self.good_image_path.exists(): self.good_image_path.mkdir(parents=True) if not self.bad_image_path.exists(): self.bad_image_path.mkdir(parents=True) self.last_image_path = None self.last_target_path = None self.current_image_path = None self.setup() def setup(self): # self.graphicsView self.scene = QGraphicsScene() rect = self.graphicsView.rect() print(rect) print(self.graphicsView.frameRect()) self.scene.setSceneRect(QRectF(rect)) self.graphicsView.setScene(self.scene) self.btnGood.clicked.connect(self.onClickGood) self.btnBad.clicked.connect(self.onClickBad) self.nextImg() def nextImg(self): print("finding next image") current_subdir = None while not current_subdir or len(list(current_subdir.iterdir())) == 0: current_subdir = next(self.raw_image_path.iterdir()) print("current_subdir: {}".format(current_subdir)) if len(list(current_subdir.iterdir())) == 0: print("deleting empty directory") os.rmdir(str(current_subdir)) current_subdir = None continue self.current_image_path = next(current_subdir.iterdir()) print("next image: {}".format(self.current_image_path)) img = Image.open(self.current_image_path) img = img.convert("RGB") width, height = img.size print("img size: {}x{}".format(*img.size)) if height > width or abs(width - height) < 250: self.displayImage(img) img.close() print( "Auto trashing image because height > width or image is almost a square" ) self.onClickBad(set_last_image=False) self.nextImg() return else: self.displayImage(img) img.close() def displayImage(self, img): self.scene.clear() w, h = img.size self.imgQ = ImageQt( img) # we need to hold reference to imgQ, or it will crash pixMap = QPixmap.fromImage(self.imgQ) self.scene.addPixmap(pixMap) self.fixImageSize() self.scene.update() def fixImageSize(self): rectf = QRectF(self.imgQ.rect()) self.scene.setSceneRect(rectf) self.graphicsView.fitInView(rectf, Qt.KeepAspectRatio) def resizeEvent(self, e): # print(self.imgQ.rect()) # rectf = QRectF(self.scene.sceneRect()) self.fixImageSize() super().resizeEvent(e) def keyPressEvent(self, e): if e.key() == Qt.Key_Y: self.onClickGood() elif e.key() == Qt.Key_N: self.onClickBad() elif e.key() == Qt.Key_Backspace: self.undo() def onClickGood(self, set_last_image=True): if self.current_image_path: if (self.good_image_path / self.current_image_path.name).exists(): print("Already exists, deleting copy") os.remove(str(self.current_image_path)) else: if set_last_image: self.last_image_path = self.current_image_path self.last_target_path = self.good_image_path / self.current_image_path.name print("moving {} -> {}".format(self.current_image_path, self.good_image_path)) shutil.move(str(self.current_image_path), str(self.good_image_path)) self.nextImg() def onClickBad(self, set_last_image=True): if self.current_image_path: if (self.bad_image_path / self.current_image_path.name).exists(): print("Already exists, deleting copy") os.remove(str(self.current_image_path)) else: if set_last_image: self.last_image_path = self.current_image_path self.last_target_path = self.bad_image_path / self.current_image_path.name print("moving {} -> {}".format(self.current_image_path, self.bad_image_path)) shutil.move(str(self.current_image_path), str(self.bad_image_path)) self.nextImg() def undo(self): if not self.last_image_path: print("Can't undo") return print("Undoing last decision: move file back {} -> {}".format( self.last_target_path, self.last_image_path)) shutil.move(str(self.last_target_path), str(self.last_image_path)) self.current_image_path = self.last_image_path self.nextImg()
class DataTaggerWindow(Ui_MainWindow): """docstring for DataTaggerWindow.""" def __init__(self): super(DataTaggerWindow, self).__init__() # self._mainWindow = QMainWindow() self.setupUi() self.raw_image_path = Path("data/raw") self.good_image_path = Path("data/good/img") self.bad_image_path = Path("data/bad/img") self.tags_file = Path("data/good/tags.csv") self.path_gen = self.good_image_path.iterdir() if not self.good_image_path.exists(): self.good_image_path.mkdir(parents=True) if not self.bad_image_path.exists(): self.bad_image_path.mkdir(parents=True) self.last_image_path = None self.current_image_path = None self.img_tags = [] self.setup() def setup(self): # self.graphicsView self.scene = QGraphicsScene() rect = self.graphicsView.rect() print(rect) print(self.graphicsView.frameRect()) self.scene.setSceneRect(QRectF(rect)) self.graphicsView.setScene(self.scene) # self.btnGood.clicked.connect(self.onClickGood) # self.btnBad.clicked.connect(self.onClickBad) # Set up tag buttons self.btnTagTemplate.setParent(None) # Hide the template font = QFont() font.setPointSize(16) self.tag_buttons = [] for tag in tags: tag_btn = QPushButton(self.centralwidget) tag_btn.setMinimumSize(QSize(0, 20)) tag_btn.setFont(font) tag_btn.setCheckable(True) tag_btn.setChecked(False) tag_btn.setObjectName("btnTag_{}".format(tag)) tag_btn.setText(tag) self.tag_buttons.append(tag_btn) self.hlayTags.addWidget(tag_btn) self.nextImg() self.nextImgUntagged() def nextImg(self): print("finding next image") # current_subdir = None # while not current_subdir or len(list(current_subdir.iterdir())) == 0: # current_subdir = next(self.raw_image_path.iterdir()) # print("current_subdir: {}".format(current_subdir)) # if len(list(current_subdir.iterdir())) == 0: # print("deleting empty directory") # os.rmdir(str(current_subdir)) # current_subdir = None # continue self.last_image_path = self.current_image_path self.current_image_path = next(self.path_gen) print("next image: {}".format(self.current_image_path)) # read tags self.img_tags = self.getTagsFromFile(self.current_image_path) print("img tags: {}".format(self.img_tags)) def applyNextImage(self): print("applying image to GUI") img = Image.open(self.current_image_path) img = img.convert("RGB") width, height = img.size print("img size: {}x{}".format(*img.size)) self.displayImage(img) img.close() self.applyTagsToButtons(self.img_tags) def nextImgUntagged(self): while len(self.img_tags) > 0: self.nextImg() if len(self.img_tags) > 0: print("img already tagged, skipping") self.applyNextImage() def displayImage(self, img): self.scene.clear() w, h = img.size self.imgQ = ImageQt( img) # we need to hold reference to imgQ, or it will crash pixMap = QPixmap.fromImage(self.imgQ) self.scene.addPixmap(pixMap) self.fixImageSize() self.scene.update() def fixImageSize(self): rectf = QRectF(self.imgQ.rect()) self.scene.setSceneRect(rectf) self.graphicsView.fitInView(rectf, Qt.KeepAspectRatio) def resizeEvent(self, e): # print(self.imgQ.rect()) # rectf = QRectF(self.scene.sceneRect()) self.fixImageSize() super().resizeEvent(e) def keyPressEvent(self, e): # key = e.key() tag_hotkeys = [ Qt.Key_Q, Qt.Key_W, Qt.Key_E, Qt.Key_R, Qt.Key_T, Qt.Key_Y, Qt.Key_U, Qt.Key_I, Qt.Key_O, Qt.Key_P, Qt.Key_BracketLeft, Qt.Key_BracketRight ] if e.key() in tag_hotkeys: idx = tag_hotkeys.index(e.key()) self.tag_buttons[idx].toggle() if e.key() == Qt.Key_Return or e.key() == Qt.Key_Enter: img_tags = self.getTagsFromButtons() self.commitTagsToFile(self.current_image_path, img_tags) self.nextImg() self.applyNextImage() elif e.key() == Qt.Key_Space: print("skipping") self.nextImg() self.applyNextImage() elif e.key() == Qt.Key_Backspace: self.undo() def getTagsFromFile(self, img_path): with open(str(self.tags_file), "r") as f: line = f.readline() while line: split = line.rstrip("\n").split(",") if split[0] == img_path.name: return split[1:] line = f.readline() return [] def commitTagsToFile(self, img_path, img_tags): print("commiting tags to file") with open(str(self.tags_file), "r") as f: lines = f.readlines() with open(str(self.tags_file), "w+") as f: found = False for line in lines: split = line.split(",") if split[0] == img_path.name: print("overwriting line") found = True f.write(",".join([img_path.name] + img_tags) + "\n") else: f.write(line) if not found: print("adding new line") f.write(",".join([img_path.name] + img_tags) + "\n") def getTagsFromButtons(self): img_tags = [] for child in self.tag_buttons: if child.isChecked(): img_tags.append(child.text()) return img_tags def applyTagsToButtons(self, img_tags): for child in self.tag_buttons: child.setChecked(child.text() in img_tags) def undo(self): if not self.last_image_path: print("Can't undo") return print("going back {} -> {}".format(self.current_image_path, self.last_image_path)) self.current_image_path = self.last_image_path self.nextImg() self.applyNextImage()
class CaptureWindow(QMainWindow): def __init__(self): super().__init__() captureImage = ImageGrab.grab(bbox=(0, 0, screenWidth, screenHeight)) self.captureImage = ImageQt(captureImage) # cv2.destroyAllWindows() # cv2.namedWindow('cvImage') # cv2.imshow('cvImage', cv2.cvtColor(np.array(captureImage), cv2.COLOR_BGR2RGB)) # 화면을 보여준다. self.sX = 0 self.sY = 0 self.eX = 0 self.eY = 0 self.drawing = False self.translatedText = "" self.translatedTextList = None self.drawingText = False self.initUI() def initUI(self): self.setWindowTitle('My First Application') # 투명 배경색 # self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 프레임바 제거 self.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint) # 항상 위에 뜨도록 self.setFocusPolicy(QtCore.Qt.StrongFocus) self.move(0, 0) self.resize(screenWidth, screenHeight) self.setFocus(True) self.activateWindow() self.raise_() self.show() def paintEvent(self, e): painter = QPainter(self) # window painter get painter.begin(self) painter.drawImage(self.rect(), self.captureImage, self.captureImage.rect()) # window painter에 전체 스크린샷찍은 image draw if self.sX != 0 and self.sY != 0 and self.eX != 0 and self.eY != 0 : painter.setPen(QPen(QColor(255, 0, 0, 255), 1)) painter.drawRect(self.sX < self.eX and self.sX or self.eX, self.sY < self.eY and self.sY or self.eY, abs(self.eX-self.sX), abs(self.eY-self.sY)) if self.drawingText: fontSize = 15 margin = 10 boxHeight = fontSize + (margin * 2) boxWidth = fontSize * len(self.translatedTextList[0]) length = len(self.translatedTextList) index = 0 for text in self.translatedTextList: boxWidth = boxWidth < fontSize * len(text) and boxWidth or fontSize * len(text) boxWidth = boxWidth * 2 for text in self.translatedTextList: painter.setPen(QColor(255,255,255)) painter.setBrush(QColor(255, 255, 255)) painter.drawRect(self.sX, (self.eY + (boxHeight*length) > screenHeight and self.sY - ((index+1)*boxHeight) or self.eY + (index*boxHeight)), boxWidth, fontSize + (margin * 2)) painter.setPen(QColor(0,0,0)) painter.setFont(QFont('나눔명조', fontSize)) painter.drawText(self.sX + margin, (self.eY + (boxHeight*length) > screenHeight and (self.sY - margin) - (index*boxHeight) or (self.eY + fontSize + margin) + (index*boxHeight)), text) index = index + 1 painter.end() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: # esc 종료 cv2.destroyAllWindows() self.close() def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.drawing = True self.drawingText = False self.sX = e.pos().x() self.sY = e.pos().y() self.eX = e.pos().x() self.eY = e.pos().y() def mouseMoveEvent(self, e): if (e.buttons() & Qt.LeftButton) & self.drawing: self.eX = e.pos().x() self.eY = e.pos().y() self.update() # paintEvent 호출 def mouseReleaseEvent(self, e): if e.button() == Qt.LeftButton: if (self.sX == self.eX) or (self.sY == self.eY) or (abs(self.eX - self.sX) < 10) or (abs(self.eY - self.sY) < 10): return self.eX = e.pos().x() self.eY = e.pos().y() # 테두리 1px 빼고 캡처 cvImage = self.captureImage.copy(self.sX < self.eX and self.sX or self.eX, self.sY < self.eY and self.sY or self.eY, abs(self.eX-self.sX), abs(self.eY-self.sY)).convertToFormat(4) cvW = cvImage.width() cvH = cvImage.height() ptr = cvImage.bits() ptr.setsize(cvImage.byteCount()) arr = np.array(ptr).reshape(cvH, cvW, 4) img = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY) cv2.imshow('gray img', img) # cv2.destroyAllWindows() # cv2.namedWindow('cvImage') # cv2.imshow('cvImage', img) # 화면을 보여준다. img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) (thresh, img) = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.imshow('OTSU img', img) out_img = cv2.GaussianBlur(img, (3, 3), 0) (thresh, out_img) = cv2.threshold(out_img, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.imshow('cvImage', out_img) self.translatedText = image_to_string(out_img, config='--tessdata-dir "tessdata" -l eng --oem 3 --psm 3') print("translatedText1: ", self.translatedText) self.translatedText = self.translatedText.replace("[^a-zA-Z\s]", "") # 영어, 공백 빼고 다 제거 if not self.translatedText.strip() == "" : # self.translatedText = papagoApi.translate(self.translatedText) # 번역 # self.translatedTextList = self.translatedText.split('\n') # 줄바꿈 split # print("translatedText2: ", self.translatedTextList) self.drawingText = True self.update() # paintEvent 호출 self.drawing = False
class PanelDraw(QWidget, Ui_PanelDraw): def __init__(self, Parent): QWidget.__init__(self) self.setupUi(self) self.Image = QImage(self.size(), QImage.Format_RGB32) self.Image.fill(Qt.white) self.dx = Parent.widget.x() / 2 self.dy = Parent.widget.y() / 2 self.readOnly = False self.drawing = False self.penSize = 2 self.penColor = Qt.black pass def mousePressEvent(self, event): if (event.button() == Qt.LeftButton) & (not self.readOnly): self.drawing = True self.lastPoint = event.pos() self.lastPoint.setX(self.lastPoint.x() + self.dx) self.lastPoint.setY(self.lastPoint.y() + self.dy) pass def mouseMoveEvent(self, event): if (event.buttons() & Qt.LeftButton) & self.drawing: painter = QPainter(self.Image) painter.setPen( QPen(self.penColor, self.penSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) pos = event.pos() pos.setX(pos.x() + self.dx) pos.setY(pos.y() + self.dy) painter.drawLine(self.lastPoint, pos) self.lastPoint = pos self.update() pass def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.drawing = False pass def paintEvent(self, event): canvas = QPainter(self) canvas.drawImage(self.rect(), self.Image, self.Image.rect()) pass def DrawImage(self, image): self.Image = ImageQt(image) self.update() pass def Clear(self): self.Image.fill(Qt.white) self.update() pass