class PointsField_NodeInstance_MainWidget(QWidget): def __init__(self, parent_node_instance): super(PointsField_NodeInstance_MainWidget, self).__init__() # leave these lines ------------------------------ self.parent_node_instance = parent_node_instance # ------------------------------------------------ self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) self.label = QLabel() pix = QPixmap(200, 200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(200, 200) self.points = [] def randomize(self, num_points): self.points.clear() for i in range(num_points): x = random.randint(0, self.label.pixmap().width()) y = random.randint(0, self.label.pixmap().height()) self.points.append({'x': x, 'y': y}) self.draw_points(self.points) return self.points def draw_points(self, points): painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.rect()) pen = QPen(QColor(255, 255, 255)) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) for p in points: painter.drawEllipse(p['x'], p['y'], 4, 4) self.repaint() def get_data(self): return {'points': self.points} def set_data(self, data): self.points = data['points'] self.draw_points(self.points) # optional - important for threading - stop everything here def removing(self): pass
def testReference(self): l = QLabel() p = QPixmap() l.setPixmap(p) # doesn't increment pixmap ref because this makes a copy self.assertEqual(sys.getrefcount(p), 2) p = l.pixmap() # this increment the reference because this is an internal pointer self.assertEqual(sys.getrefcount(p), 3) p2 = l.pixmap() self.assertEqual(p, p2)
class ShowPoints_NodeInstance_MainWidget(QWidget, MWB): def __init__(self, params): MWB.__init__(self, params) QWidget.__init__(self) self.setStyleSheet(''' background-color: #0C1C23; border: none; ''') self.setLayout(QVBoxLayout()) self.label = QLabel() pix = QPixmap(200, 200) self.label.setPixmap(pix) #self.setContentMargins(0) self.layout().addWidget(self.label) self.resize(200, 200) def show_points(self, points): painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(Qt.NoPen) painter.setBrush(QColor('#0C1C23')) painter.drawRect(self.rect()) pen = QPen(QColor('#ffffff')) painter.setPen(pen) painter.setBrush(QBrush(QColor('#ffffff'))) for p in points: painter.drawEllipse(p[0]*self.label.pixmap().width(), p[1]*self.label.pixmap().height(), 2, 2) self.repaint() def get_data(self): return {} def set_data(self, data): pass def remove_event(self): pass
def testReference(self): l = QLabel() p = QPixmap() l.setPixmap( p) # doesn't increment pixmap ref because this makes a copy self.assertEqual(sys.getrefcount(p), 2) p = l.pixmap() # this used to increment the reference because this is # an internal pointer, but not anymore since we don't create # a copy # self.assertEqual(sys.getrefcount(p), 3) self.assertEqual(sys.getrefcount(p), 2) p2 = l.pixmap() self.assertEqual(p, p2)
class Viewer(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.scaleFactor = 1.0 self.imageLabel = QLabel() self.imageLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabel.setScaledContents(True) self.imageLabel.show() self.markers = Markers(self.imageLabel, IMG_FILE[:-3] + "json") km = KeysManager(self.markers) self.scrollArea = MyScrollArea(self.zoom, self.click, km.keyEventKB) self.scrollArea.setWidget(self.imageLabel) self.scrollArea.setVisible(False) def load_image(self): self.imageLabel.setPixmap(load_img()) self.scrollArea.setVisible(True) self.imageLabel.adjustSize() def zoom(self, scr_x, scr_y, factor): # # figure out pixel coordinate where mouse pointer is # hsb = self.scrollArea.horizontalScrollBar() cur_pixel_x = (hsb.value() + scr_x) / self.scaleFactor vsb = self.scrollArea.verticalScrollBar() cur_pixel_y = (vsb.value() + scr_y) / self.scaleFactor # # rescale the image # self.scaleFactor *= factor self.imageLabel.resize(self.scaleFactor * self.imageLabel.pixmap().size()) self.markers.zoom(self.scaleFactor) # # adjust scroll so the we zoom in/out at where we are pointing # left_pixel_x = cur_pixel_x - (scr_x / self.scaleFactor) hsb.setValue(left_pixel_x * self.scaleFactor) top_pixel_y = cur_pixel_y - (scr_y / self.scaleFactor) vsb.setValue(top_pixel_y * self.scaleFactor) def click(self, x, y): x /= self.scaleFactor y /= self.scaleFactor self.markers.add(x, y, self.scaleFactor) def save_markers(self): self.markers.save()
class ShowPoints_NodeInstance_MainWidget(QWidget): def __init__(self, parent_node_instance): super(ShowPoints_NodeInstance_MainWidget, self).__init__() # leave these lines ------------------------------ self.parent_node_instance = parent_node_instance # ------------------------------------------------ self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) self.label = QLabel() pix = QPixmap(200,200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(200, 200) def show_points(self, points): painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.rect()) pen = QPen(QColor(255, 255, 255)) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) for p in points: painter.drawEllipse(p['x']*self.label.pixmap().width(), p['y']*self.label.pixmap().height(), 4, 4) self.repaint() def get_data(self): return {} def set_data(self, data): pass def remove_event(self): pass
class %CLASS%(QWidget, MWB): def __init__(self, params): MWB.__init__(self, params) QWidget.__init__(self) self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) self.label = QLabel() pix = QPixmap(200,200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(200, 200) def show_points(self, points): painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.rect()) pen = QPen(QColor(255, 255, 255)) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) for p in points: painter.drawEllipse(p['x']*self.label.pixmap().width(), p['y']*self.label.pixmap().height(), 4, 4) self.repaint() def get_data(self): return {} def set_data(self, data): pass def remove_event(self): pass
class QLabelTest(UsesQApplication): '''Test case for calling QLabel.setPixmap''' def setUp(self): super(QLabelTest, self).setUp() self.label = QLabel() def tearDown(self): del self.label super(QLabelTest, self).tearDown() def testSetPixmap(self): p1 = QPixmap(5, 5) p2 = QPixmap(10, 10) self.label.setPixmap(p1) self.assertIsNotNone(self.label.pixmap()) # PYSIDE-150: # When a new QPixmap is assigned to a QLabel, # the previous one needs to be cleared. # This means we should not keep a copy of the QPixmap # on Python-side. # Getting pointer to the QPixmap ret_p = self.label.pixmap() self.assertIsNot(p1, ret_p) # Save the address of the pointer ret_p_addr = shiboken.getCppPointer(ret_p) # Remove the QPixmap del ret_p # Set new QPixmap self.label.setPixmap(p2) # There should be no pointers remaining with the same # address that our QPixmap p1 because it was deleted # using `del ret_p` self.assertTrue(all(shiboken.getCppPointer(o) != ret_p_addr for o in shiboken.getAllValidWrappers()))
class ShowPoints_NodeInstance_MainWidget(QWidget): def __init__(self, parent_node_instance): super(ShowPoints_NodeInstance_MainWidget, self).__init__() # leave these lines ------------------------------ self.parent_node_instance = parent_node_instance self.package_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), '../../../') # ------------------------------------------------ self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) self.label = QLabel() pix = QPixmap(200, 200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(200, 200) self.points = [] def show_points(self, points): self.points = points painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.rect()) pen = QPen(QColor(255, 255, 255)) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) for p in self.points: painter.drawEllipse(p['x'], p['y'], 4, 4) self.repaint() def get_data(self): data = {'pints': self.points} # ... return data def set_data(self, data): self.points = data['points'] # optional - important for threading - stop everything here def removing(self): pass
class CameraFeed(QWidget): def __init__(self, id, app: QApplication, *args, **kwargs): super().__init__(*args, **kwargs) self.id = id self.app = app self.box = QHBoxLayout() self.setLayout(self.box) self.video_frame = QLabel() self.video_frame.setScaledContents(True) self.video_frame.setMinimumSize(1, 1) self.video_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setMinimumSize(1, 1) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.box.addWidget(self.video_frame) self.box.setContentsMargins(0, 0, 0, 0) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) def startReceiving(self): self.feed_receiver = FeedReceiver(self, self.id, self.app) self.setVideoFramePlaceHolder() self.feed_receiver.signals.imageReady.connect(self.updateImage) self.feed_receiver.start() def updateImage(self, data: QImage): img = QPixmap() img.convertFromImage(data) self.video_frame.setPixmap(img) def setVideoFramePlaceHolder(self): img = QImage(self.feed_receiver.width, self.feed_receiver.width // 16 * 9, QImage.Format_Grayscale8) img.fill(2) self.updateImage(img) def saveImage(self, name=None): fn = 'img/' + (name or datetime.datetime.now().isoformat()) + '.jpg' print(fn) self.video_frame.pixmap().save(fn, 'JPEG', 100)
class WidgetTest(QWidget): def __init__(self): super().__init__() self.label = QLabel() canvas = QPixmap(400, 300) canvas.fill(Qt.white) self.label.setPixmap(canvas) self.draw_something() def draw_something(self): painter = QPainter(self.label.pixmap()) names=["Empty","N","E","EN","S","NS","ES","ENS","W","NW","EW","ENW","SW","NSW","ESW","ENSW"] images = [QtGui.QPixmap("images/"+name+".bmp", format="bmp") for name in names] painter.drawPixmap(QtCore.QPoint(0,0) , images[9]) painter.drawPixmap(QtCore.QPoint(50,0) , images[3]) painter.drawPixmap(QtCore.QPoint(0,50) , images[13]) painter.drawPixmap(QtCore.QPoint(50,50) , images[6]) painter.end()
class drawForm (baseForm): """ Drawing form """ @classmethod def getNewWindow(cls, targetImage=None, axeSize=200, layer=None, parent=None): wdgt = drawForm(targetImage=targetImage, axeSize=axeSize, layer=layer, parent=parent) wdgt.setWindowTitle(layer.name) return wdgt def __init__(self, targetImage=None, axeSize=500, layer=None, parent=None): super().__init__(layer=layer, targetImage=targetImage, parent=parent) self.options = None pushButton1 = QPushButton(' Undo ') pushButton1.adjustSize() pushButton2 = QPushButton(' Redo ') pushButton2.adjustSize() pushButton1.clicked.connect(self.undo) pushButton2.clicked.connect(self.redo) spacingSlider = QSlider(Qt.Horizontal) spacingSlider.setObjectName('spacingSlider') spacingSlider.setRange(1,60) spacingSlider.setTickPosition(QSlider.TicksBelow) spacingSlider.setSliderPosition(10) spacingSlider.sliderReleased.connect(self.parent().label.brushUpdate) self.spacingSlider = spacingSlider jitterSlider = QSlider(Qt.Horizontal) jitterSlider.setObjectName('jitterSlider') jitterSlider.setRange(0, 100) jitterSlider.setTickPosition(QSlider.TicksBelow) jitterSlider.setSliderPosition(0) jitterSlider.sliderReleased.connect(self.parent().label.brushUpdate) self.jitterSlider = jitterSlider orientationSlider = QSlider(Qt.Horizontal) orientationSlider.setObjectName('orientationSlider') orientationSlider.setRange(0, 360) orientationSlider.setTickPosition(QSlider.TicksBelow) orientationSlider.setSliderPosition(180) orientationSlider.sliderReleased.connect(self.parent().label.brushUpdate) self.orientationSlider = orientationSlider # sample self.sample = QLabel() #self.sample.setMinimumSize(200, 100) pxmp = QPixmap(250,100) pxmp.fill(QColor(255, 255, 255, 255)) self.sample.setPixmap(pxmp) qpp = QPainterPath() qpp.moveTo(QPointF(20, 50)) qpp.cubicTo(QPointF(80, 25), QPointF(145, 70), QPointF(230, 60)) # c1, c2, endPoint self.samplePoly = qpp.toFillPolygon(QTransform()) # we want an unclosed polygon self.samplePoly.removeLast() # layout l = QVBoxLayout() l.setAlignment(Qt.AlignTop) hl = QHBoxLayout() hl.setAlignment(Qt.AlignHCenter) hl.addWidget(pushButton1) hl.addWidget(pushButton2) l.addLayout(hl) l.addWidget(QLabel('Brush Dynamics')) hl1 = QHBoxLayout() hl1.addWidget(QLabel('Spacing')) hl1.addWidget(spacingSlider) l.addLayout(hl1) hl2 = QHBoxLayout() hl2.addWidget(QLabel('Jitter')) hl2.addWidget(jitterSlider) l.addLayout(hl2) hl3 = QHBoxLayout() hl3.addWidget(QLabel('Orientation')) hl3.addWidget(self.orientationSlider) l.addLayout(hl3) l.addWidget(self.sample) self.setLayout(l) self.adjustSize() self.setDefaults() self.setWhatsThis( """ <b>Drawing :</b><br> Choose a brush family, flow, hardness and opacity. """ ) # end of setWhatsThis def setDefaults(self): try: self.dataChanged.disconnect() except RuntimeError: pass self.dataChanged.connect(self.updateLayer) self.updateSample() def updateLayer(self): """ dataChanged slot """ l = self.layer # l.tool.setBaseTransform() l.applyToStack() l.parentImage.onImageChanged() def updateSample(self): pxmp = self.sample.pixmap() pxmp.fill(QColor(0,0,0,0)) brushFamily.brushStrokePoly(pxmp, self.samplePoly, self.layer.brushDict) self.sample.repaint() def undo(self): try: self.layer.sourceImg = self.layer.history.undo(saveitem=self.layer.sourceImg.copy()).copy() # copy is mandatory self.updateLayer() except ValueError: pass def redo(self): try: self.layer.sourceImg = self.layer.history.redo().copy() # copy is mandatory self.updateLayer() except ValueError: pass def reset(self): self.layer.tool.resetTrans()
class %CLASS%(QWidget, MWB): def __init__(self, params): MWB.__init__(self, params) QWidget.__init__(self) self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) # settings widget settings_widget = QWidget() settings_widget.setLayout(QHBoxLayout()) self.connect_lines_check_box = QCheckBox('connect lines linear') settings_widget.layout().addWidget(self.connect_lines_check_box) self.layout().addWidget(settings_widget) # points area self.label = QLabel() pix = QPixmap(300,200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(300, 200) self.values = [] def update(self, new_vals): self.values = new_vals if len(self.values) == 0: return painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.label.rect()) pen = QPen(QColor(255, 255, 255)) pen.setWidth(1) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) x_old = -1 y_old = -1 div = max(self.values) for i in range(len(self.values)): v = self.values[i] x = i * (self.label.width()/len(self.values)) y = self.label.height()-self.label.height()*v/div if self.connect_lines_check_box.isChecked() and i>0: painter.drawLine(x_old, y_old, x, y) else: painter.drawEllipse(x-1, y-1, 2, 2) x_old = x y_old = y self.repaint() def get_data(self): return {'connect lines linear': self.connect_lines_check_box.isChecked()} def set_data(self, data): self.connect_lines_check_box.setChecked(data['connect lines linear']) def remove_event(self): pass
class Dicom_Browser(QWidget): draw_state: bool = False erase_state: bool = False point_pick: bool = False nj_points = [] nj_points_ready = Signal() series_id: str mask: np.array def __init__(self): super().__init__() self.initUI() self.rubberBand: QRubberBand = QRubberBand(QRubberBand.Line, self.image_label) def initUI(self): self.image = DicomImage() self.pixmap = QPixmap() self.image_label = QLabel() self.image_label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.image_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.image_label.setPixmap(self.pixmap) self.tags_view = Dicom_Tags_Widget(['']) self.tools = Dicom_ImageToolsWidget() self.tabs_widget = self.__inti_tab_widget__( [self.tags_view, self.tools]) self.tabs_widget.setMaximumWidth(600) image_layout = QVBoxLayout() image_layout.setContentsMargins(0, 0, 0, 0) image_layout.addWidget(self.image_label) image_group = QGroupBox() image_group.setStyleSheet("margin:0; padding: 0; border: 0;") image_group.setContentsMargins(0, 0, 0, 0) image_group.setLayout(image_layout) splitter = QSplitter() splitter.addWidget(image_group) splitter.addWidget(self.tabs_widget) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(splitter) self.tools.pen_selected.connect(self.pen_select) self.tools.erase_btn.clicked.connect(self.erase_btn_click) self.tools.slider.valueChanged.connect(self.slider_changed) self.tools.processing_btn.clicked.connect(self.send_nn_segmentation) self.tools.load_mask_btn.clicked.connect(self.load_nifti_mask_click) self.tools.save_mask_btn.clicked.connect(self.save_nifti_mask_click) self.tools.nj_segment_btn.clicked.connect(self.nj_segment_click) self.nj_points_ready.connect(self.nj_segment) def set_image(self): self.pixmap = QPixmap.fromImage(self.image.get_slice_as_QImage()) self.image_label.setPixmap(self.pixmap) self.set_tags() def update_mask(self): self.mask = np.zeros([ self.image.get_shape()[0], self.image.get_shape()[1], self.image.get_slice_amount() ], np.int) self.draw_mask() def load_series(self, path): if isinstance(path, list): if len(path) == 1: path = path[0] else: path = os.path.dirname(path[0]) + '/' self.image.load_dicom(path) self.set_image() if self.image.is_series(): self.set_slider_maximum() self.tools.slider.setDisabled(False) else: self.tools.slider.setDisabled(True) self.set_tags() self.update_tags() self.update_mask() def set_tags(self): result = [] for elem in self.image.slice().iterall(): result.append([str(elem.tag), elem.name, str(elem.value)]) return result def update_tags(self): self.tags_view.model.update(self.set_tags()) self.tags_view.model.layoutChanged.emit() # MOUSE EVENTS def wheelEvent(self, event): if self.image_label.underMouse(): delta = event.delta() if delta > 0: self.image.next_slice() elif delta < 0: self.image.pre_slice() self.set_image() self.tools.slider.setSliderPosition(self.image.get_slice_index()) self.update_tags() self.draw_mask() self.update() def mousePressEvent(self, e): if self.image_label.underMouse(): if self.draw_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos) self.draw_mask_point(self.pos) self.update() elif self.erase_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos, 0) self.set_image() self.draw_mask() self.update() elif self.point_pick: point = [ self.point_on_image(e).x(), self.point_on_image(e).x(), self.image.get_slice_index() ] self.nj_points.append(point) if len(self.nj_points) == 2: self.point_pick = False QApplication.restoreOverrideCursor() self.nj_points_ready.emit() else: self.origin = e.pos() if not self.rubberBand: self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) self.rubberBand.setGeometry(QRect(self.origin, QSize())) self.rubberBand.show() def mouseMoveEvent(self, e): if self.image_label.underMouse(): if self.draw_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos) # self.mask[int(self.pos.y())][int(self.pos.x())][self.image.get_slice_index()] = 255 self.draw_mask_point(self.pos) self.update() elif self.erase_state: self.pos = self.point_on_image(e) self.set_mask_pixels(self.pos, 0) # self.mask[int(self.pos.y())][int(self.pos.x())][self.image.get_slice_index()] = 0 self.set_image() self.draw_mask() self.update() else: self.rubberBand.setGeometry( QRect(self.origin, e.pos()).normalized()) def mouseReleaseEvent(self, event): if self.image_label.underMouse(): if self.draw_state: return self.rubberBand.hide() def keyPressEvent(self, event): # Re-direct ESC key to closeEvent if event.key() == Qt.Key_Escape: if self.point_pick: self.point_pick = not self.point_pick QApplication.restoreOverrideCursor() # IMAGE SLIDER def set_slider_maximum(self): self.tools.set_slider_maximum(self.image.get_slice_amount() - 1) def slider_changed(self): self.image.set_slice_index(self.tools.slider.value()) self.set_image() self.update_tags() self.draw_mask() self.update() def pen_select(self): self.draw_state = self.tools.pen_btn.isChecked() def __init_slider(self) -> QSlider: slider = QSlider() slider.setOrientation(Qt.Horizontal) slider.setMaximumWidth(self.image_label.width()) slider.setMinimum(0) slider.setMaximum(self.image.get_slice_amount()) slider.setTickInterval(1) slider.setSliderPosition(1) slider.valueChanged.connect(self.slider_changed) if not self.image.is_series(): slider.setHidden(True) return slider def __inti_tab_widget__(self, widgets: list) -> object: tabs_widget = QTabWidget() tabs_widget.setTabPosition(QTabWidget.South) tabs_widget.setMinimumWidth(50) for wdg in widgets: tabs_widget.addTab(wdg, wdg.tab_name) return tabs_widget # MASKING def send_nn_segmentation(self): # Dicom_BrowserCtrl.save_mask(self, self.mask, 'res/H-DenseUNet-master_v1/livermask/0.nii') ctrl = Dicom_BrowserCtrl() head, tail = os.path.split(os.path.split(self.image.dicom_dir)[0]) ctrl.image_to_nn(tail, self.mask, self.image.get_shape()[0], self.image.get_shape()[1]) def set_mask(self): img = self.__arr_to_QImage(self.mask[:, :, self.image.get_slice_index()].T()) self.mask_pixmap = QPixmap.fromImage(img) self.mask_label.setPixmap(self.mask_pixmap) def draw_mask(self): try: if not np.array_equal( self.mask[:, :, self.image.get_slice_index()], np.zeros( [self.image.get_shape()[0], self.image.get_shape()[1]])): it = np.nditer(self.mask[:, :, self.image.get_slice_index()], flags=['multi_index']) for pixel in it: if pixel != 0: point = QPoint(it.multi_index[1], it.multi_index[0]) self.draw_mask_point(point, 1) except Exception: self.update_mask() def set_mask_pixels(self, center_point: QPoint, value=255): it = np.nditer(self.mask[:, :, self.image.get_slice_index()], flags=['multi_index']) size = int(self.tools.get_size() / 2) - 1 x = center_point.x() y = center_point.y() for pixel in it: if x - size <= it.multi_index[ 1] <= x + size and y + size >= it.multi_index[ 0] >= y - size: self.mask[it.multi_index[0]][it.multi_index[1]][ self.image.get_slice_index()] = value def draw_mask_point(self, point, pen_size: int = None): if pen_size is None: pen_size = self.tools.get_size() painter = QPainter(self.image_label.pixmap()) painter.setPen( QPen(self.tools.mask_color, pen_size, Qt.SolidLine, Qt.SquareCap, Qt.RoundJoin)) painter.drawPoint(point) def erase_btn_click(self): self.erase_state = not self.erase_state self.tools.erase_btn.setChecked(self.erase_state) if self.draw_state: self.draw_state = not self.draw_state self.tools.pen_btn.setChecked(self.draw_state) def load_nifti_mask_click(self): ctrl = Dicom_BrowserCtrl() self.mask = ctrl.load_nitfit_mask() self.draw_mask() self.update() def save_nifti_mask_click(self): Dicom_BrowserCtrl.save_mask(self, self.mask) def nj_segment_click(self): QApplication.setOverrideCursor(QCursor(Qt.CrossCursor)) self.point_pick = True def nj_segment(self): ctrl = Dicom_BrowserCtrl() ctrl.nj_segment(self.image.dicom_dir, self.nj_points) self.nj_points = [] self.mask = ctrl.load_nitfit_mask('data/.tmp.nii') self.draw_mask() self.update() def point_on_image(self, e): x_offset, y_offset = self.__image_offset() pos = QPoint(e.x() - x_offset, e.y() - y_offset) return pos def __image_offset(self): x_offset = (self.image_label.width() - self.pixmap.width()) / 2 y_offset = (self.image_label.height() - self.pixmap.height()) / 2 return x_offset, y_offset def __arr_to_QImage(self, arr_img): img = PIL.Image.fromarray(arr_img) img = img.convert("L") result = ImageQt(img) return result
class SandyScreen(QWidget): def __init__(self, root): QWidget.__init__(self) self.root = root # Setting state vars self.app_running = True self.ctrl_down = False self.in_fullscreen = False self.in_menu = False self.on_pause = True # Setting animation vars self.timer_delay = 10 self.phase = 1 self.delta_per_tick = 1 / 30 self.xpmsz = None self.geo = [0, 0, 0, 0] # Creating timer and sandpile self.timer = QTimer(self) self.seed = None self.piletype = None self.sandpile = None self.reroll_pile() # Generating pause icon self.pause_icon = Image.new('RGBA', size=(60, 60)) for i in range(60): for j in range(60): self.pause_icon.putpixel( (j, i), (255, 255, 255, 0 if 20 < j < 40 else 100)) # Initialising UI and running self.init_ui() self.show() def init_ui(self): self.setMinimumSize(600, 400) self.setWindowTitle('Sandy Screen') # Menu widget self.menu = SandyMenu(self) # Sandbox container widget and its background and canvas label stack self.sandbox = QWidget(self) self.sandbox.setGeometry(0, 0, 600, 400) self.sandbox_bg = QLabel(self.sandbox) self.sandbox_bg.setGeometry(0, 0, 600, 400) self.sandbox_bg.setPixmap( QPixmap(['1 1 1 1', '1 c #000000', '1']).scaled(self.sandbox_bg.size())) self.canvases = [QLabel(self.sandbox), QLabel(self.sandbox)] for c in self.canvases: c.setAlignment(Qt.AlignCenter) c.setGeometry(0, 0, 600, 400) self.canvases[1].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) self.sandpile.topple_step() self.canvases[0].setPixmap(QPixmap(generate_xpm(self.sandpile)[0])) # Opacity effect on the upper frame label self.opeff = QGraphicsOpacityEffect(self.canvases[-1]) self.opeff.setOpacity(1) self.canvases[-1].setGraphicsEffect(self.opeff) # Main stack layout self.layout = QStackedLayout(self) self.layout.addWidget(self.sandbox) self.layout.addWidget(self.menu) # Overlay pause icon label self.pause_label = QLabel(self) self.pause_label.setAlignment(Qt.AlignCenter) self.pause_label.setPixmap(QPixmap(ImageQt.ImageQt(self.pause_icon))) def restart_pile(self): del self.sandpile self.sandpile = self.piletype(copy.deepcopy(self.seed), frozen=True, timed=False, vocal=False) print('restart called') def reroll_pile(self, piletype=None, seed=None): if seed: self.seed = seed else: v = random.randint(8, 33) self.seed = [[v for j in range(_X)] for i in range(_Y)] if piletype: self.piletype = piletype else: v = random.randint(0, 3) self.piletype = [t4f, t6hf, t6vf, t8f][v] self.sandpile = self.piletype(copy.deepcopy(self.seed), frozen=True, timed=False, vocal=False) def run(self): self.root.exec_() def closeEvent(self, event): self.timer.stop() self.app_running = False def keyPressEvent(self, event): k = event.key() if k == 16777236: self.update_sandbox(1) # if k == _CTRL: self.ctrl_down = True if self.ctrl_down: if k == _M: self.toggle_menu() # Menu toggled on Ctrl+M elif k == _R: self.reroll_pile() else: if k == _F11: self.toggle_fullscreen() elif k == _SPACE and not self.in_menu: self.toggle_pause() def keyReleaseEvent(self, event): if event.key() == _CTRL: self.ctrl_down = False def resizeEvent(self, event): self.pause_label.setGeometry(self.rect()) sbg = self.sandbox.geometry() sbs = self.sandbox.size() self.sandbox_bg.setGeometry(sbg) self.sandbox_bg.setPixmap(self.sandbox_bg.pixmap().scaled( self.sandbox_bg.size())) for c in self.canvases: c.setGeometry(sbg) c.setPixmap(c.pixmap().scaled(sbs, Qt.KeepAspectRatio)) ### Fix this. def toggle_fullscreen(self): self.in_fullscreen = not self.in_fullscreen self.showFullScreen() if self.in_fullscreen else self.showNormal() def toggle_menu(self): self.in_menu = not self.in_menu if self.in_menu: self.layout.setCurrentIndex(1) self.pause_label.setVisible(False) self.on_pause = True self.root.restoreOverrideCursor() else: self.layout.setCurrentIndex(0) if self.on_pause: self.pause_label.raise_() self.pause_label.setVisible(True) else: self.root.setOverrideCursor(Qt.BlankCursor) self.resizeEvent(None) def toggle_pause(self): self.on_pause = not self.on_pause if self.on_pause: self.timer.stop() self.pause_label.raise_() self.pause_label.setVisible(True) self.root.restoreOverrideCursor() else: self.pause_label.setVisible(False) self.timer.singleShot(self.timer_delay, lambda: self.update_sandbox(0)) self.root.setOverrideCursor(Qt.BlankCursor) def update_sandbox(self, mode): if not self.in_menu: if mode == self.on_pause: self.phase -= self.delta_per_tick if self.phase <= 0: self.canvases[-1].setPixmap(self.canvases[0].pixmap()) self.phase = 1 self.opeff.setOpacity(self.phase) if not self.sandpile.topple_step() and not self.on_pause: self.toggle_pause() xpm, sz = generate_xpm(self.sandpile) self.canvases[0].setPixmap( QPixmap(xpm).scaled(self.sandbox.size(), Qt.KeepAspectRatio)) else: self.opeff.setOpacity( math.pow(math.sin(math.pi * self.phase / 2), 2)) if mode == 0 and self.app_running: self.timer.singleShot(self.timer_delay, lambda: self.update_sandbox(0))
class Canvas (QWidget): def __init__(self): QWidget.__init__(self) self.file = "mug.webp" self.__img = cv2.imread(self.file) self.__mask = np.zeros(1) self.original = cv2.imread(self.file) self.__thirdChannelMask = np.dstack((self.__mask, self.__mask, self.__mask)) self.__nseg = 1 self.__sig = 1 self.__comp = 1 self.nSlider = QSlider(orientation=Qt.Horizontal) self.sigSlider = QSlider(orientation=Qt.Horizontal) self.thicSlider = QSlider(orientation=Qt.Horizontal) self.resize_spinbox = QSpinBox(self) self.resize_spinbox.setRange(1, 100) self.resize_spinbox.setValue(100) self.resize_spinbox.setSuffix(" %") self.double_spin_width = QDoubleSpinBox(self) self.double_spin_width.setSuffix(" px") self.double_spin_width.setValue(0) self.double_spin_width.setRange(1, 2000) self.double_spin_height = QDoubleSpinBox(self) self.double_spin_height.setSuffix(" px") self.double_spin_height.setValue(0) self.double_spin_height.setRange(1, 2000) self.zeroModeCheck = QCheckBox("Usar SLIC0") self.__highlightcolor = QColor(255, 255, 255) self.__transparency = 0.5 self.__AllColors = [self.__highlightcolor.toTuple()[:3]] nLabel = QLabel("Numero de segmentos:") sigLabel = QLabel("Sigma:") thicLabel = QLabel("Compactação:") resizeLabel = QLabel("Fator de resize da image:") makssizeLabel = QLabel("Dimensão da mascara de saída:") self.__label = QLabel() nLabel.setToolTip("O número aproximado de labels da imagem segmentada") sigLabel.setToolTip("A largura da Gaussiana") thicLabel.setToolTip("Equilibra a proximidade das cores e a proximidade do espaço, maiores valores tornam os Superpixels mais quadrados") self.nSlider.setMinimum(1) self.nSlider.setMaximum(100) self.sigSlider.setMinimum(1) self.sigSlider.setMaximum(100) self.thicSlider.setMinimum(1) self.thicSlider.setMaximum(100) glayout1 = QGridLayout() glayout1.addWidget(nLabel, 0, 0) glayout1.addWidget(self.nSlider, 0, 1) glayout1.addWidget(sigLabel, 1, 0) glayout1.addWidget(self.sigSlider, 1, 1) glayout1.addWidget(thicLabel, 2, 0) glayout1.addWidget(self.thicSlider, 2, 1) glayout2 = QGridLayout() glayout2.addWidget(resizeLabel, 0, 0) glayout2.addWidget(self.resize_spinbox, 0, 1) glayout2.addWidget(self.zeroModeCheck, 0, 2) glayout2.addWidget(makssizeLabel, 1, 0) glayout2.addWidget(self.double_spin_width, 1, 1) glayout2.addWidget(self.double_spin_height, 1, 2) glayout2.setColumnStretch(3, 1) self.__label.setAlignment(Qt.AlignLeft | Qt.AlignTop) mainlayout = QVBoxLayout() mainlayout.addLayout(glayout1) mainlayout.addLayout(glayout2) mainlayout.addStretch(1) mainlayout.addWidget(self.__label) mainlayout.addStretch(1) mainlayout.setAlignment(Qt.AlignCenter) self.setLayout(mainlayout) self.nSlider.sliderReleased.connect(self.onNsegChange) self.sigSlider.sliderReleased.connect(self.onSigChange) self.thicSlider.sliderReleased.connect(self.onCompChange) self.__label.mousePressEvent = self.Highlight self.resize_spinbox.valueChanged.connect(self.Resize) self.open_image(self.__img) def getBackground(self): mask = self.__thirdChannelMask.copy() mask_r = mask[:, :, 2] mask_g = mask[:, :, 1] mask_b = mask[:, :, 0] offImage = list() for color in self.__AllColors: b_off = mask_b != color[2] g_off = mask_g != color[1] r_off = mask_r != color[0] aux = np.logical_and(b_off, g_off) offImage.append(np.logical_and(aux, r_off)) final = offImage[0] for cut in offImage: final = np.logical_or(final, cut) return final def changeImage(self): self.__mask = slic(self.__img, n_segments=self.__nseg, compactness=self.__comp, sigma=self.__sig, convert2lab=True, slic_zero=self.zeroModeCheck.isChecked()) mask = self.__mask.copy() mask = np.dstack((mask, mask, mask)) mask = img_as_ubyte(mask) self.__thirdChannelMask = mask img = cv2.addWeighted(self.__img, 1, mask, 0.5, 0) marc_img = mark_boundaries(img, self.__mask) self.open_image(marc_img) def load_image(self): self.__img = cv2.imread(self.file) self.original = self.__img self.double_spin_width.setValue(self.__img.shape[1]) self.double_spin_height.setValue(self.__img.shape[0]) val = self.resize_spinbox.value() newDim = int(self.__img.shape[1]*val/100), int(self.__img.shape[0]*val/100) self.__img = cv2.resize(self.__img, newDim) self.open_image(self.__img) def open_image(self, img): if img.shape[2] == 4: qformat = QImage.Format_RGBA8888 else: qformat = QImage.Format_RGB888 copy = img_as_ubyte(img) qimg = QImage(copy.data, copy.shape[1], copy.shape[0], copy.strides[0], qformat).rgbSwapped() pixmap = QPixmap.fromImage(qimg) self.__label.setPixmap(pixmap) self.__label.adjustSize() @Slot() def onNsegChange(self): self.__nseg = self.nSlider.value() self.changeImage() @Slot() def onSigChange(self): self.__sig = self.sigSlider.value() self.changeImage() @Slot() def onCompChange(self): self.__comp = self.thicSlider.value() self.changeImage() @Slot() def onFileOpen(self): self.thicSlider.setValue(1) self.nSlider.setValue(1) self.sigSlider.setValue(1) diag = QFileDialog() file = diag.getOpenFileName()[0] if file != "": self.file = file self.load_image() @Slot() def onSaveFile(self): diag = QFileDialog() file = diag.getSaveFileName()[0] if self.file != "": self.__label.pixmap().save(file) @Slot() def onSaveMask(self): diag = QFileDialog() file = diag.getSaveFileName()[0] final_img = cv2.resize(self.__mask, (self.double_spin_width.value(), self.double_spin_height.value())) if file != "": cv2.imwrite(file, final_img) @Slot() def Highlight(self, e): if e.x() < 0 or e.x() > self.__img.shape[1] or e.y() < 0 or e.y() > self.__img.shape[0]: return self.__mask = flood_fill(self.__mask, (e.y(), e.x()), 255) self.__thirdChannelMask[:, :, 2] = flood_fill(self.__thirdChannelMask[:, :, 2], (e.y(), e.x()), self.__highlightcolor.red()) self.__thirdChannelMask[:, :, 1] = flood_fill(self.__thirdChannelMask[:, :, 1], (e.y(), e.x()), self.__highlightcolor.green()) self.__thirdChannelMask[:, :, 0] = flood_fill(self.__thirdChannelMask[:, :, 0], (e.y(), e.x()), self.__highlightcolor.blue()) img = cv2.addWeighted(self.__img, 1, self.__thirdChannelMask, self.__transparency, 0) marc_img = mark_boundaries(img, self.__mask) self.open_image(marc_img) @Slot() def exportBinary(self): diag = QFileDialog() file = diag.getSaveFileName()[0] mask = self.__thirdChannelMask.copy() final = self.getBackground() b = mask[:, :, 0] g = mask[:, :, 1] r = mask[:, :, 2] b[final] = 0 g[final] = 0 r[final] = 0 final_img = cv2.resize(mask, (int(self.double_spin_width.value()), int(self.double_spin_height.value()))) if file != "": cv2.imwrite(file, final_img) @Slot() def onRemoveBackgroud(self): box = QMessageBox() box.setText("Selecione a cor do background") box.setIcon(QMessageBox.Information) box.exec() diag = QColorDialog() backColor = diag.getColor() final = self.getBackground() b = self.__img[:, :, 0] g = self.__img[:, :, 1] r = self.__img[:, :, 2] b[final] = backColor.blue() g[final] = backColor.green() r[final] = backColor.red() self.open_image(self.__img) @Slot() def Resize(self): val = self.resize_spinbox.value() newDim = int(self.original.shape[1] * val / 100), int(self.original.shape[0] * val / 100) self.__img = cv2.resize(self.original, newDim) self.open_image(self.__img) @Slot() def setHighlightColor(self, color): self.__highlightcolor = color @Slot() def getAllColors(self, colors): self.__AllColors = colors @Slot() def setTran(self, value): self.__transparency = 1- value/100 @Slot() def onUndo(self): self.thicSlider.setValue(1) self.nSlider.setValue(1) self.sigSlider.setValue(1) self.onNsegChange() self.onSigChange() self.onCompChange() self.__img = self.original self.open_image(self.__img)
class MainWindow(QMainWindow): DIMENSION = 560 placement_aleatoire = True nb_robots = 0 def __init__(self, game): """ La fenêtre principale est initialisée avec l'organisation suivante : +--------------------------------------------------------------------------+ | self.menu = self.menuBar() | | | +--------------------------------------------------------------------------+ | toolbar = QToolBar() (déplacement/sélection des robots, | | boutons annuler, indice et solution) | +------------------------layout0 = QHBoxLayout()---------------------------+ | layout2 = QHBoxLayout() + moves_label | | l + | | | a grid_choice | nb_robots_choice | (affichage des | +-y--------------------+----------------------+ L | | o | a mouvements effectués) | | u | y | | t +--o-------------------------+ | = label = QLabel() | u | | Q | t tip_label | | V contient la grille de jeu | 3 | | B | (Affichage de l'indice| | o | = | | x | si demandé) | | L | Q | | a +--V+------------------------+ | y | B solution_label | | o | o | | u | x (Affichage de la | | t | | | | solution si demandée) | +---------------------------------------------+----------------------------+ """ super().__init__() self.game = game self.initial_game_state = self.game.get_state() self.number_moves = 0 self.setWindowTitle("Robot Ricochet") self.resize(self.DIMENSION + 150, self.DIMENSION + 100) # label contient la grille de jeu self.label = QLabel() canvas = QPixmap(self.DIMENSION, self.DIMENSION) canvas.fill(Qt.white) self.label.setPixmap(canvas) # layout0 contient, à gauche, les barres d'outils et la grille, # et à droite, la liste des états et l'indice affiché par le solveur layout0 = QHBoxLayout() layout0.setContentsMargins(0, 0, 0, 0) layout0.setSpacing(0) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout2 = QHBoxLayout() # Choix de la grille self.choice_of_grid_menu() # choix du nombre de robots self.nb_robots_choice_menu() # CheckBox placement aléatoire widget3 = QCheckBox("Placement aléatoire des robots et de l'objectif") widget3.setCheckState(Qt.Checked) widget3.stateChanged.connect(self.placer_aleatoirement) # layout2 contient les 3 widgets horizontaux de choix de grille, robots et aléa layout2.addWidget(self.grid_choice) layout2.addWidget(self.nb_robots_choice) #layout2.addWidget(widget3) layout2.setContentsMargins(0, 0, 0, 0) layout2.setSpacing(0) widget2 = QWidget() widget2.setLayout(layout2) layout.addWidget(widget2) layout.addWidget(self.label) # liste des mouvement effectués, indice et solution: layout3 = QVBoxLayout() layout3.setContentsMargins(0, 0, 0, 0) layout3.setSpacing(0) self.moves_label = QLabel() self.print_moves_list() self.tip_label = QLabel() self.solution_label = QLabel() layout3.addWidget(self.moves_label) layout3.addWidget(self.tip_label) layout3.addWidget(self.solution_label) layout0.addLayout(layout) layout0.addLayout(layout3) widget = QWidget() widget.setLayout(layout0) self.setCentralWidget(widget) # Menu self.menu = self.menuBar() self.file_menu = self.menu.addMenu("File") self.help_menu = self.menu.addMenu("Aide et instructions") # A faire self.size_fenetre = self.geometry() # Play QAction play_action = QAction("Réinitialiser !", self) play_action.triggered.connect(self.replay) self.file_menu.addAction(play_action) # Open_grid QAction open_grid_action = QAction("Ouvrir une grille", self) open_grid_action.setShortcut('Ctrl+O') open_grid_action.triggered.connect(self.open_grid) self.file_menu.addAction(open_grid_action) # Open_game QAction open_game_action = QAction("Ouvrir un jeu", self) open_game_action.triggered.connect(self.open_game) self.file_menu.addAction(open_game_action) # Save_grid QAction save_grid_action = QAction("Enregistrer cette grille", self) save_grid_action.triggered.connect(self.save_grid) self.file_menu.addAction(save_grid_action) # Save_game QAction save_game_action = QAction("Enregistrer ce jeu", self) save_game_action.triggered.connect(self.save_game) self.file_menu.addAction(save_game_action) # Exit QAction exit_action = QAction("Quitter", self) exit_action.setShortcut(QKeySequence.Quit) exit_action.triggered.connect(self.close) self.file_menu.addAction(exit_action) # Help QAction help_action = QAction("Aide", self) help_action.triggered.connect(self.help) self.help_menu.addAction(help_action) self.toolbar_menus() #Le robot rouge est sélectionné par défaut self.selected_robot = 'R' self.draw_robots_and_goal() def replay(self): """ on remet l'état initial du jeu """ self.game.set_state(self.initial_game_state) self.game.moves_list = [] self.game.states_list = deque([self.game.state_start], maxlen=100) self.unprint_moves_list() self.number_moves = 0 self.draw_robots_and_goal() def help(self): """ Ouvre une fenêtre d'aide""" self.help_windows = Help_window() self.help_windows.exec_() def toolbar_menus(self): """ Affiche la barre d'icônes permettant de diriger les robots et de les sélectionner""" # Toolbar toolbar = QToolBar("Game toolbar") self.addToolBar(toolbar) # Flèche gauche button_West = QAction(QIcon(ICON_PATH + "arrow-180.png"), "West", self) button_West.setStatusTip("Aller à gauche") button_West.triggered.connect(self.onButtonWestClick) button_West.setCheckable(False) button_West.setShortcut(QKeySequence("Left")) toolbar.addAction(button_West) # Flèche droite button_East = QAction(QIcon(ICON_PATH + "arrow.png"), "Est", self) button_East.setStatusTip("Aller à droite") button_East.triggered.connect(self.onButtonEastClick) button_East.setCheckable(False) button_East.setShortcut(QKeySequence("Right")) toolbar.addAction(button_East) # Flèche Haut button_North = QAction(QIcon(ICON_PATH + "arrow-090.png"), "North", self) button_North.setStatusTip("Aller vers le haut") button_North.triggered.connect(self.onButtonNorthClick) button_North.setCheckable(False) button_North.setShortcut(QKeySequence("Up")) toolbar.addAction(button_North) # Flèche Bas button_South = QAction(QIcon(ICON_PATH + "arrow-270.png"), "South", self) button_South.setStatusTip("Aller vers le Bas") button_South.triggered.connect(self.onButtonSouthClick) button_South.setCheckable(False) button_South.setShortcut(QKeySequence("Down")) toolbar.addAction(button_South) # Selection robot actif button_Red = QPushButton("&Red") button_Red.setIcon(QIcon(ICON_PATH + "icon_R.png")) button_Red.setAutoExclusive(True) button_Red.setCheckable(True) button_Red.setShortcut(QKeySequence("R")) button_Red.toggled.connect(self.onButtonRedClick) button_Green = QPushButton("&Green") button_Green.setIcon(QIcon(ICON_PATH + "icon_G.png")) button_Green.setAutoExclusive(True) button_Green.setCheckable(True) button_Green.setShortcut(QKeySequence("G")) button_Green.toggled.connect(self.onButtonGreenClick) button_Blue = QPushButton("&Blue") button_Blue.setIcon(QIcon(ICON_PATH + "icon_B.png")) button_Blue.setAutoExclusive(True) button_Blue.setCheckable(True) button_Blue.setShortcut(QKeySequence("B")) button_Blue.toggled.connect(self.onButtonBlueClick) button_Yellow = QPushButton("&Yellow") button_Yellow.setIcon(QIcon(ICON_PATH + "icon_Y.png")) button_Yellow.setAutoExclusive(True) button_Yellow.setCheckable(True) button_Yellow.setShortcut(QKeySequence("Y")) button_Yellow.toggled.connect(self.onButtonYellowClick) # Boutton d'annulation (revient en arrière d'un coup) button_undo = QPushButton("&Undo") button_undo.setIcon(QIcon(ICON_PATH + "undo.jpg")) button_undo.setAutoExclusive(False) button_undo.setCheckable(False) button_undo.setShortcut(QKeySequence("U")) button_undo.clicked.connect(self.onButtonUndoClick) # Boutton d'indice : lance le solveur pour donner l'indice du prochain coup à effectuer button_tip = QPushButton("&Tip") button_tip.setIcon(QIcon(ICON_PATH + "icon_tip.png")) button_tip.setAutoExclusive(False) button_tip.setCheckable(False) button_tip.setShortcut(QKeySequence("T")) button_tip.clicked.connect(self.onButtonTipClick) # Boutton Solution : lance le solveur pour afficher une liste d'actions à effectuer pour résoudre le jeu button_solution = QPushButton("&Solution") button_solution.setIcon(QIcon(ICON_PATH + "icon_solution.png")) button_solution.setAutoExclusive(False) button_solution.setCheckable(False) button_solution.setShortcut(QKeySequence("S")) button_solution.clicked.connect(self.onButtonSolutionClick) toolbar.addWidget(button_Red) toolbar.addWidget(button_Green) toolbar.addWidget(button_Blue) toolbar.addWidget(button_Yellow) toolbar.addWidget(button_undo) toolbar.addWidget(button_tip) toolbar.addWidget(button_solution) def open_grid(self): """ Ouvre une boîte de dialogue permettant de charger une grille existante sur le disque dur""" filename, filter = QFileDialog.getOpenFileName( self, 'selectionner un fichier contenant une grille', './grids', '*.json') board, = Board.load_from_json(filename) self.game.add_board(board) self.number_moves = 0 self.group = Robot_group() self.game = Game(self.game.board, self.group, self.game.goal) self.unprint_moves_list() self.draw_grid() def open_game(self): """ Ouvre une boîte de dialogue permettant de charger un jeu existant sur le disque dur""" filename, filter = QFileDialog.getOpenFileName( self, 'selectionner un fichier contenant un jeu', './games', '*.json') self.game = Game.load_from_json(filename) self.initial_game_state = self.game.get_state() self.number_moves = 0 self.unprint_moves_list() self.draw_robots_and_goal() def save_grid(self): """ Ouvre une boîte de dialogue permettant d'enregistrer la grille affichée sur le disque dur""" filename, _ = QFileDialog.getSaveFileName( self, "Save Grid As", "", "JSON (*.JSON *.json);;" "All files(*.*)", ) if filename: self.game.board.save_as_json(filename) def save_game(self): """ Ouvre une boîte de dialogue permettant d'enregistrer le jeu actuel sur le disque dur Si le joueur entre ou sélectionne un nom de fichier, le eju est sauvegardé dans ce fichier """ filename, _ = QFileDialog.getSaveFileName( self, "Save game As", "", "JSON (*.JSON *.json);;" "All files(*.*)", ) if filename: self.game.save_to_json(filename) def print_moves_list(self): """ Affichage de la liste des mouvements effectués dans le label "moves_label" """ self.moves_label.setText("Mouvements effectués : \n" + str(self.game.moves_list).replace(', ', '\n')) self.moves_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) def unprint_moves_list(self): """ réinitialisation du label "moves_label" pour cacher la liste des mouvements effectués. """ self.moves_label.setText(" ") self.moves_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) def print_tip(self): """ Affichage du conseil généré par le solveur dans le label "tip_label" """ self.tip_label.setText("Et si vous essayiez ce mouvement : \n" + str(self.tip) + " ?") self.tip_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) def unprint_tip(self): """ réinitialisation du label "tip_label" pour cacher le conseil généré par le solveur. """ self.tip_label.setText(" ") self.tip_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) self.solution_label.setText(" ") def choice_of_grid_menu(self): self.grid_choice = QComboBox() self.grid_choice.insertItems( 0, ("Grille 6x6", "Grille 8x8", "Grille 10x10", "Grille 12x12", "Grille 14x14", "Grille 16x16", "Grille aléatoire 16x16")) self.grid_choice.setGeometry(0, 0, 180, 40) self.grid_choice.activated.connect(self.choix_grille) def choix_grille(self, i): """ Lors du choix d'une nouvelle grille, le jeu est réinitialisé et redessiné, les robots et l'objectif sont masqués. """ # pour ouvrir les vieux .txt # name_grid = './test' + str(i + 1) + '.txt' # fd = open(name_grid,'r') # A = Board.load_from_json(fd) if i == 0: A, = Board.load_from_json(GRIDS_PATH + 'grid 6x6.json') elif i == 1: A, = Board.load_from_json(GRIDS_PATH + 'grid 8x8.json') elif i == 2: A, = Board.load_from_json(GRIDS_PATH + 'grid 10x10.json') elif i == 3: A, = Board.load_from_json(GRIDS_PATH + 'grid 12x12.json') elif i == 4: A, = Board.load_from_json(GRIDS_PATH + 'grid 14x14.json') elif i == 5: A, = Board.load_from_json(GRIDS_PATH + 'grid 16x16.json') else: # Pour ouvrir une grille aléatoire classique A = Board.new_classic() self.game.add_board(A) self.number_moves = 0 self.group = Robot_group() self.game = Game(self.game.board, self.group, self.game.goal) self.draw_grid() # choix du nombre de robots def nb_robots_choice_menu(self): self.nb_robots_choice = QComboBox() self.nb_robots_choice.insertItems( 0, ("1 robot", "2 robots", "3 robots", "4 robots")) self.nb_robots_choice.setGeometry(0, 0, 40, 40) self.nb_robots_choice.activated.connect(self.choix_nb_robots) def choix_nb_robots(self, i): """ Les robots et l'objectif sont placés aléatoirement. L'extension """ self.group = Robot_group() self.game = Game(self.game.board, self.group, self.game.goal) self.nb_robots = i + 1 robots_pos = [0] * self.nb_robots robots_list = [0] * self.nb_robots robots_colors = [i for i in RColors] if self.placement_aleatoire: for i in range(self.nb_robots): x = randint(0, self.game.board.width - 1) y = randint(0, self.game.board.height - 1) while ((x, y) in robots_pos): x = randint(0, self.game.board.width - 1) y = randint(0, self.game.board.height - 1) robots_pos[i] = (x, y) robots_list[i] = Robot(self.game.robots, robots_colors[i], (x, y)) x = randint(0, self.game.board.width - 1) y = randint(0, self.game.board.height - 1) goal = Goal(RColors(randint(1, self.nb_robots)), (x, y)) self.game = Game(self.game.board, self.group, self.game.goal) self.game.add_goal(goal) self.initial_game_state = self.game.get_state() self.draw_robots_and_goal() else: fp = open(GAMES_PATH + DEFAULT_GAME, 'r') self.game = Game.load_from_json(fp) fp.close() def draw_grid(self): """ Dessine la grille de jeu en juxtaposant les images contenant chaque case. Chaque image est redimensionnée et ajustée à la taille de la grille. """ painter = QPainter(self.label.pixmap()) names = [ "Empty", "N", "E", "EN", "S", "NS", "ES", "ENS", "W", "NW", "EW", "ENW", "SW", "NSW", "ESW", "ENSW" ] images = [ QPixmap(IMAGES_PATH + name + ".bmp", format="bmp") for name in names ] for x in range(0, self.game.board.width): for y in range(0, self.game.board.height): painter.drawPixmap( QPoint(self.DIMENSION / self.game.board.height * y, self.DIMENSION / self.game.board.width * x), images[int(str(self.game.board.grid[x][y]))].scaled( self.DIMENSION / self.game.board.width, self.DIMENSION / self.game.board.height)) self.update() painter.end() def draw_robots_and_goal(self): self.draw_grid() painter = QPainter(self.label.pixmap()) goal_img_name = ICON_PATH + "/goal_" + str( self.game.goal.color) + ".png" painter.drawPixmap( QPoint( self.DIMENSION / self.game.board.height * self.game.goal.position[1], self.DIMENSION / self.game.board.width * self.game.goal.position[0]), QPixmap(goal_img_name, format="png").scaled( self.DIMENSION / self.game.board.width * 0.9, self.DIMENSION / self.game.board.height * 0.9)) images = [ QPixmap(ICON_PATH + "robot_" + str(color) + ".png", format="png") for color in self.game.color_keys ] for i, robot in enumerate(self.game.robots): painter.drawPixmap( QPoint( self.DIMENSION / self.game.board.height * self.game.robots[robot].position[1], self.DIMENSION / self.game.board.width * self.game.robots[robot].position[0]), images[i].scaled(self.DIMENSION / self.game.board.width * 0.8, self.DIMENSION / self.game.board.height)) self.update() painter.end() def onButtonEastClick(self, s): self.game.do_action(self.selected_robot + 'E') self.draw_robots_and_goal() self.number_moves += 1 self.print_moves_list() self.unprint_tip() if self.game.is_won(): self.game_is_won() def onButtonWestClick(self, s): self.game.do_action(self.selected_robot + 'W') self.draw_robots_and_goal() self.number_moves += 1 self.print_moves_list() self.unprint_tip() if self.game.is_won(): self.game_is_won() def onButtonNorthClick(self, s): self.game.do_action(self.selected_robot + 'N') self.draw_robots_and_goal() self.number_moves += 1 self.print_moves_list() self.unprint_tip() if self.game.is_won(): self.game_is_won() def onButtonSouthClick(self, s): self.game.do_action(self.selected_robot + 'S') self.draw_robots_and_goal() self.number_moves += 1 self.print_moves_list() self.unprint_tip() if self.game.is_won(): self.game_is_won() def placer_aleatoirement(self): """ inverse la sélection de la checkBox """ self.placement_aleatoire = not (self.placement_aleatoire) def onButtonRedClick(self, s): if s: self.selected_robot = 'R' def onButtonGreenClick(self, s): if s: self.selected_robot = 'G' def onButtonBlueClick(self, s): if s: self.selected_robot = 'B' def onButtonYellowClick(self, s): if s: self.selected_robot = 'Y' def onButtonUndoClick(self, s): """ Annule le dernier coup effectué """ if self.number_moves != 0: self.game.undo() self.number_moves -= 1 self.print_moves_list() self.unprint_tip() self.draw_robots_and_goal() def solve(self): """tip_game contient une copie du jeu courant, pour l'utiliser par le solveur""" self.game.save_to_json('tip_game.json') self.tip_game = Game.load_from_json('tip_game.json') return (solveur(self.tip_game).find_solution()) def onButtonTipClick(self, s): """ La solution renvoyée par le solveur est de la forme (True/False, liste d'actions à effectuer). On récupère ici la première action.""" self.tip = self.solve()[1][0] self.print_tip() def onButtonSolutionClick(self, s): self.solution = self.solve()[1] self.solution_label.setText( "Pour gagner, vous auriez pu effectuer cette suite de mouvements : \n" + str(self.solution) + ".") self.solution_label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) def game_is_won(self): """ Fonction lancée quand l'objectif est atteint. On génère une fonction exit_windows dont le code de retour 1, 2 ou 3 valide le choix : 1 : replay : on remet l'état initial du jeu 2 : new game : on choisit une grille aleatoire 3 : exit : on quitte le jeu. """ self.exit_windows = Exit_window(self.number_moves) self.exit_windows.exec_() if self.exit_windows.retStatus == 1: #replay : on remet l'état initial du jeu self.replay() elif self.exit_windows.retStatus == 2: #new game : on choisit une grille aleatoire self.choix_grille(1) self.choix_nb_robots(3) self.unprint_moves_list() elif self.exit_windows.retStatus == 3: #exit : on quitte le jeu exit()
class ViewWidget(QScrollArea): """Widget providing an interactive viewport.""" def __init__(self, app): QScrollArea.__init__(self) self.app = app self.image = QLabel() self.image.setScaledContents(True) self.image.setMouseTracking(True) self.image.mouseMoveEvent = self.mouseMoveEvent_over_image self.image.mousePressEvent = self.mousePressEvent_over_image self.image.mouseReleaseEvent = self.mouseReleaseEvent_over_image self.zoom_factor = 1 """The current zoom factor of the image.""" self.mouse_action = 0 """The current action on mouse move. Can be *ROI*, *WINDOW* or *PAN*.""" self.last_position = None """The last position, from which mouse events were processed.""" self.setMouseTracking(True) self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setWidget(self.image) # Hide scrollbars self.horizontalScrollBar().setStyleSheet("QScrollBar { height: 0 }") self.verticalScrollBar().setStyleSheet("QScrollBar { width: 0 }") def set(self, pixmap): """Display the image in *pixmap*.""" self.image.setPixmap(pixmap) def zoom(self, factor, relative=True): """Set the zoom level for the displayed image. By default, the new zoom factor will be relative to the current zoom factor. If *relative* is set to False, *factor* will be used as the new zoom factor.""" if self.app.dataset is None \ or (relative and (0.1 >= self.zoom_factor * factor >= 100)): return self.zoom_factor = self.zoom_factor * factor if relative else factor self.image.resize(self.zoom_factor * self.image.pixmap().size()) v_scroll = int(factor * self.verticalScrollBar().value() + ( (factor - 1) * self.verticalScrollBar().pageStep() / 2)) self.verticalScrollBar().setValue(v_scroll) h_scroll = int(factor * self.horizontalScrollBar().value() + ( (factor - 1) * self.horizontalScrollBar().pageStep() / 2)) self.horizontalScrollBar().setValue(h_scroll) def zoom_fit(self): """Zoom the displayed image to fit the available viewport.""" image = self.image.pixmap().size() viewport = self.size() if image.height() == 0 or image.width() == 0: return v_zoom = viewport.height() / image.height() h_zoom = viewport.width() / image.width() self.zoom(min(v_zoom, h_zoom) * 0.99, False) def mousePressEvent(self, event): # pylint: disable=C0103 """Handle pan and window functionality on mouse button down.""" if event.buttons() == Qt.LeftButton \ and event.modifiers() == Qt.NoModifier: self.mouse_action = "PAN" elif event.buttons() == Qt.MiddleButton: self.mouse_action = "WINDOW" self.last_position = event.screenPos() def mouseReleaseEvent(self, event): # pylint: disable=C0103,W0613 """Handle RoI functionality on mouse button up.""" if self.mouse_action == "ROI": self.app.recalculate() self.last_position = None self.mouse_action = 0 def mouseMoveEvent(self, event): # pylint: disable=C0103 """Handle pan, window and RoI functionality on mouse move.""" self.app.window.show_status("") if self.mouse_action == "PAN": vertical = self.verticalScrollBar().value() \ + self.last_position.y() - event.screenPos().y() horizontal = self.horizontalScrollBar().value() \ + self.last_position.x() - event.screenPos().x() self.verticalScrollBar().setValue(vertical) self.horizontalScrollBar().setValue(horizontal) self.last_position = event.screenPos() elif self.mouse_action == "WINDOW": move = self.last_position.x() - event.screenPos().x() scale = self.last_position.y() - event.screenPos().y() self.last_position = event.screenPos() self.app.mode.adjust_window(move, scale) self.app.refresh() elif self.mouse_action == "ROI": x_pos = event.pos().x() if event.pos().x() <= self.image.width() \ else self.image.width() y_pos = event.pos().y() if event.pos().y() <= self.image.height() \ else self.image.height() if self.app.tool is not None: self.app.tool.end_roi(int(x_pos / self.zoom_factor), int(y_pos / self.zoom_factor)) self.app.refresh() def mousePressEvent_over_image(self, event): # pylint: disable=C0103 """Handle RoI functionality on mouse button down over the image. Hands off contorl to *mousePressEvent* when appropriate.""" if event.buttons() == Qt.LeftButton \ and event.modifiers() == Qt.ControlModifier: self.mouse_action = "ROI" self.last_position = event.pos() if self.app.tool is not None: x_pos = event.pos().x() y_pos = event.pos().y() self.app.tool.start_roi(int(x_pos / self.zoom_factor), int(y_pos / self.zoom_factor)) else: self.mousePressEvent(event) def mouseMoveEvent_over_image(self, event): # pylint: disable=C0103 """Handle value display functionality on mouse move over the image. Call *mouseMoveEvent* for pan, window and RoI functionality.""" self.mouseMoveEvent(event) x_coord = int((self.horizontalScrollBar().value() + event.pos().x()) // self.zoom_factor) y_coord = int((self.verticalScrollBar().value() + event.pos().y()) // self.zoom_factor) slice_ = self.app.dataset.get_pixeldata(self.app.slice) shape = slice_.shape if (x_coord < shape[0] and y_coord < shape[1]): value = slice_[x_coord, y_coord] self.app.window.show_status("{} x {} - {:.4g}".format( x_coord, y_coord, value)) def mouseReleaseEvent_over_image(self, event): # pylint: disable=C0103 """Call *mouseReleaseEvent* on mouse button up for RoI functionality.""" self.mouseReleaseEvent(event) def wheelEvent(self, event): # pylint: disable=C0103 """Handle scroll wheel events in the viewport. Scroll - Change current slice up or down. Alt+Scroll - Change current scan up or down. Strg+Scroll - Zoom the current image in or out.""" if event.modifiers() == Qt.NoModifier: slice_ = int(numpy.sign(event.delta())) self.app.select_slice(slice_, True) elif event.modifiers() == Qt.ControlModifier: self.zoom(0.8 if event.delta() < 0 else 1.25) elif event.modifiers() == Qt.AltModifier: scan = int(numpy.sign(event.delta())) self.app.select_scan(scan, True)
class ShowValHist_NodeInstance_MainWidget(QWidget): def __init__(self, parent_node_instance): super(ShowValHist_NodeInstance_MainWidget, self).__init__() # leave these lines ------------------------------ self.parent_node_instance = parent_node_instance # ------------------------------------------------ self.setStyleSheet(''' background-color: #333333; ''') self.setLayout(QVBoxLayout()) # settings widget settings_widget = QWidget() settings_widget.setLayout(QHBoxLayout()) self.connect_lines_check_box = QCheckBox('connect lines linear') settings_widget.layout().addWidget(self.connect_lines_check_box) self.layout().addWidget(settings_widget) # points area self.label = QLabel() pix = QPixmap(300, 200) self.label.setPixmap(pix) self.layout().addWidget(self.label) self.resize(300, 200) self.values = [] def update(self, new_vals): self.values = new_vals painter = QPainter(self.label.pixmap()) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(QPen('#333333')) painter.setBrush(QColor('#333333')) painter.drawRect(self.label.rect()) pen = QPen(QColor(255, 255, 255)) pen.setWidth(1) painter.setPen(pen) painter.setBrush(QBrush(Qt.white)) x_old = -1 y_old = -1 for i in range(len(self.values)): v = self.values[i] x = i * (self.label.width() / len(self.values)) y = self.label.height() - self.label.height() * v if self.connect_lines_check_box.isChecked() and i > 0: painter.drawLine(x_old, y_old, x, y) else: painter.drawEllipse(x - 1, y - 1, 2, 2) x_old = x y_old = y self.repaint() def get_data(self): return { 'connect lines linear': self.connect_lines_check_box.isChecked() } def set_data(self, data): self.connect_lines_check_box.setChecked(data['connect lines linear']) # optional - important for threading - stop everything here def removing(self): pass
class Screenshot(QWidget): def __init__(self): super().__init__() self.init_UI() def init_UI(self): splitter = QSplitter(Qt.Horizontal) splitter.splitterMoved.connect(self.resizeEvent) # hor_layout = QHBoxLayout() self.original_pixmap = QPixmap() self.screenshot_label = QLabel(self) self.screenshot_label.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding) self.screenshot_label.setAlignment(Qt.AlignCenter) self.screenshot_label.resize( self.size().width()*0.45, self.screenshot_label.size().height()) self.text_edit = QTextEdit() splitter.addWidget(self.screenshot_label) splitter.addWidget(self.text_edit) self.save_screenshot_button = QPushButton("Save Screenshot", self) self.save_screenshot_button.clicked.connect(self.save_screenshot) self.save_text_button = QPushButton("Save Text", self) self.save_text_button.setEnabled(False) self.save_text_button.clicked.connect(self.save_text) self.take_rect_screenshoot_button = QPushButton( 'Take region screenshoot', self) self.take_rect_screenshoot_button.clicked.connect( self.create_rect_screenshot) self.quit_screenshot_button = QPushButton("Quit", self) self.quit_screenshot_button.clicked.connect(QApplication.quit) screenshot_buttons_layout = QHBoxLayout() screenshot_buttons_layout.addWidget(self.save_screenshot_button) screenshot_buttons_layout.addWidget(self.save_text_button) screenshot_buttons_layout.addWidget(self.quit_screenshot_button) self.lang_combo_box = CheckableComboBox() self.lang_combo_box.addItem("eng") self.lang_combo_box.addItem("ukr") self.lang_combo_box.addItem("rus") self.lang_combo_box.set_item_check("eng", True) self.recognition_button = QPushButton('Recognize', self) self.recognition_button.setEnabled(False) self.recognition_button.clicked.connect(self.run_recognition) self.negative_check_box = QCheckBox('Negative') self.negative_check_box.setToolTip( 'Make negative picture for better recognition') self.grayscale_check_box = QCheckBox('Grayscale') self.grayscale_check_box.setChecked(True) self.grayscale_check_box.setToolTip( 'Make grayscale picture for better recognition') recognition_buttons_layout = QHBoxLayout() recognition_buttons_layout.addWidget(self.take_rect_screenshoot_button) recognition_buttons_layout.addWidget(self.recognition_button) recognition_buttons_layout.addWidget(self.lang_combo_box) recognition_buttons_layout.addWidget(self.negative_check_box) recognition_buttons_layout.addWidget(self.grayscale_check_box) main_layout = QVBoxLayout(self) main_layout.addWidget(splitter) main_layout.addLayout(recognition_buttons_layout) main_layout.addLayout(screenshot_buttons_layout) self.setLayout(main_layout) self.shoot_screen() self.setWindowTitle("Screenshot recognition") self.resize(600, 600) self.screenshot_size = [] @Slot() def new_screenshot(self): if self.hide_this_window_check_box.isChecked(): self.hide() self.new_screenshot_button.setDisabled(True) if self.delay_spin_box.value() != 0: QTimer.singleShot(self.delay_spin_box.value() * 1000, self.shoot_screen) else: QTimer.singleShot(100, self.shoot_screen) @Slot() def save_screenshot(self): frmat = '.png' initial_path = QStandardPaths.writableLocation( QStandardPaths.PicturesLocation) if not initial_path: initial_path = QDir.currentPath() initial_path += '/Screenshot-' + \ str(datetime.now()).replace(' ', '_') + frmat file_dialog = QFileDialog(self, "Save as", initial_path) file_dialog.setAcceptMode(QFileDialog.AcceptSave) file_dialog.setFileMode(QFileDialog.AnyFile) if file_dialog.exec() != QDialog.Accepted: return file_name = file_dialog.selectedFiles()[0] if not self.original_pixmap.save(file_name): logger.error("The image could not be saved to \"{}\".".format( QDir.toNativeSeparators(file_name))) QMessageBox.warning(self, "Save Error", "The image could not be saved to \"{}\".".format( QDir.toNativeSeparators(file_name))) @Slot() def save_text(self): frmat = '.txt' initial_path = QStandardPaths.writableLocation( QStandardPaths.DocumentsLocation) if not initial_path: initial_path = QDir.currentPath() initial_path += '/Screenshot_Text-' + \ str(datetime.now()).replace(' ', '_') + frmat file_dialog = QFileDialog(self, "Save as", initial_path) file_dialog.setAcceptMode(QFileDialog.AcceptSave) file_dialog.setFileMode(QFileDialog.AnyFile) if file_dialog.exec() != QDialog.Accepted: return file_name = file_dialog.selectedFiles()[0] with open(file_name, 'w') as wf: wf.write(self.text_edit.toPlainText()) @Slot() def create_rect_screenshot(self): self.recognition_button.setEnabled(True) self.new_window = FullScreenDraw(self) # if self.hide_this_window_check_box.isChecked(): self.hide() self.new_window.showFullScreen() # self.show() @Slot() def run_recognition(self): folder_path = 'temp_img' logger.debug("running recognition") if not os.path.exists(folder_path): os.mkdir(folder_path) logger.debug("Directory " + folder_path + " created") else: logger.debug("Directory " + folder_path + " already yet") if self.original_pixmap.save(folder_path + '/img001.png'): logger.debug("Picture img001 created") logger.debug("List_item_checked: " + str(self.lang_combo_box.list_item_checked())) res = self.recognition( folder_path + '/img001.png', self.lang_combo_box.list_item_checked()) self.text_edit.setText(res) self.save_text_button.setEnabled(True) if not res: QMessageBox.information( self, "Recognition failed", "Can't recognize text") else: QMessageBox.information( self, "Recognition complete", "Recognition complete") try: rmtree(folder_path) logger.debug("Directory " + folder_path+" deleted") except OSError as e: logger.error("Error: %s : %s" % (folder_path, e.strerror)) def recognition(self, path, langs=['eng']): try: from PIL import Image, ImageOps except ImportError: import Image import pytesseract srt_lang = '+'.join(langs) im = Image.open(path) if self.negative_check_box.isChecked(): im = ImageOps.invert(im.convert('RGB')) if self.grayscale_check_box.isChecked(): im = im.convert('LA') if logger.isEnabledFor(logging.DEBUG): if not os.path.exists('debug'): os.mkdir('debug') im.save('debug/test_' + str(datetime.now() ).replace(' ', '_') + '.png', 'PNG') res = pytesseract.image_to_string(im, lang=srt_lang) return res @Slot() def shoot_screen(self, windo=0): screen = QGuiApplication.primaryScreen() window = QWindow() window = self.windowHandle() if window: screen = window.screen() if not screen: return if type(windo) in (list, tuple): self.original_pixmap = screen.grabWindow( QApplication.desktop().winId(), *windo) else: self.original_pixmap = screen.grabWindow( QApplication.desktop().winId(), windo) self.update_screenshot_label() # self.new_screenshot_button.setDisabled(False) # if self.hide_this_window_check_box.isChecked(): self.show() def update_screenshot_label(self): self.screenshot_label.setPixmap(self.original_pixmap.scaled(self.screenshot_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) def resizeEvent(self, event): scaled_size = QSize() scaled_size = self.original_pixmap.size() scaled_size.scale(self.screenshot_label.size(), Qt.KeepAspectRatio) if scaled_size != self.screenshot_label.pixmap().size(): self.update_screenshot_label()