Skip to content

Commit f878e3e

Browse files
Merge pull request #1448 from MouseLand/error_reporting
allow errors to propagate past Qt, add debug logging
2 parents 94ae120 + 90ebe22 commit f878e3e

2 files changed

Lines changed: 56 additions & 42 deletions

File tree

cellpose/gui/guiparts.py

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""
22
Copyright © 2025 Howard Hughes Medical Institute, Authored by Carsen Stringer , Michael Rariden and Marius Pachitariu.
33
"""
4+
import logging
5+
import traceback
46
from qtpy import QtGui, QtCore
57
from qtpy.QtGui import QPixmap, QDoubleValidator
68
from qtpy.QtWidgets import QWidget, QDialog, QGridLayout, QPushButton, QLabel, QLineEdit, QDialogButtonBox, QComboBox, QCheckBox, QVBoxLayout
@@ -135,6 +137,16 @@ def setup(self):
135137

136138
# return ChannelChoose, ChannelLabels
137139

140+
def unsilence_exceptions(func):
141+
""" Wrapper to unsilence Qt exceptions and re-raise them """
142+
def wrapper(*args, **kwargs):
143+
try:
144+
return func(*args, **kwargs)
145+
except Exception as e:
146+
logger = logging.getLogger(__name__)
147+
logger.critical(f"Uncaught exception in {func.__name__}")
148+
logger.debug(''.join(traceback.format_exception(type(e), e, e.__traceback__)))
149+
return wrapper
138150

139151
class ModelButton(QPushButton):
140152

@@ -582,6 +594,7 @@ def __init__(self, parent=None, border=None, lockAspect=False, enableMouse=True,
582594
self.parent = parent
583595
self.axHistoryPointer = -1
584596

597+
@unsilence_exceptions
585598
def keyPressEvent(self, ev):
586599
"""
587600
This routine should capture key presses in the current view box.
@@ -629,58 +642,56 @@ def __init__(self, image=None, viewbox=None, parent=None, **kargs):
629642
self.parent.current_stroke = []
630643
self.parent.in_stroke = False
631644

645+
@unsilence_exceptions
632646
def mouseClickEvent(self, ev):
633647
if not (self.parent.masksOn or
634648
self.parent.outlinesOn) and self.parent.removing_region:
635649
return
636650

637-
try:
638-
is_right_click = ev.button() == QtCore.Qt.RightButton
639-
if self.parent.loaded \
640-
and (is_right_click or ev.modifiers() & QtCore.Qt.ShiftModifier and not ev.double())\
641-
and not self.parent.deleting_multiple:
642-
if not self.parent.in_stroke:
643-
ev.accept()
644-
self.create_start(ev.pos())
645-
self.parent.stroke_appended = False
646-
self.parent.in_stroke = True
647-
self.drawAt(ev.pos(), ev)
648-
else:
649-
ev.accept()
650-
self.end_stroke()
651-
self.parent.in_stroke = False
652-
elif not self.parent.in_stroke:
653-
y, x = int(ev.pos().y()), int(ev.pos().x())
654-
if y >= 0 and y < self.parent.Ly and x >= 0 and x < self.parent.Lx:
655-
if ev.button() == QtCore.Qt.LeftButton and not ev.double():
656-
idx = self.parent.cellpix[self.parent.currentZ][y, x]
657-
if idx > 0:
658-
if ev.modifiers() & QtCore.Qt.ControlModifier:
659-
# delete mask selected
660-
self.parent.remove_cell(idx)
661-
elif ev.modifiers() & QtCore.Qt.AltModifier:
662-
self.parent.merge_cells(idx)
663-
elif self.parent.masksOn and not self.parent.deleting_multiple:
664-
self.parent.unselect_cell()
665-
self.parent.select_cell(idx)
666-
elif self.parent.deleting_multiple:
667-
if idx in self.parent.removing_cells_list:
668-
self.parent.unselect_cell_multi(idx)
669-
self.parent.removing_cells_list.remove(idx)
670-
else:
671-
self.parent.select_cell_multi(idx)
672-
self.parent.removing_cells_list.append(idx)
651+
is_right_click = ev.button() == QtCore.Qt.RightButton
652+
if self.parent.loaded \
653+
and (is_right_click or ev.modifiers() & QtCore.Qt.ShiftModifier and not ev.double())\
654+
and not self.parent.deleting_multiple:
655+
if not self.parent.in_stroke:
656+
ev.accept()
657+
self.create_start(ev.pos())
658+
self.parent.stroke_appended = False
659+
self.parent.in_stroke = True
660+
self.drawAt(ev.pos(), ev)
661+
else:
662+
ev.accept()
663+
self.end_stroke()
664+
self.parent.in_stroke = False
665+
elif not self.parent.in_stroke:
666+
y, x = int(ev.pos().y()), int(ev.pos().x())
667+
if y >= 0 and y < self.parent.Ly and x >= 0 and x < self.parent.Lx:
668+
if ev.button() == QtCore.Qt.LeftButton and not ev.double():
669+
idx = self.parent.cellpix[self.parent.currentZ][y, x]
670+
if idx > 0:
671+
if ev.modifiers() & QtCore.Qt.ControlModifier:
672+
# delete mask selected
673+
self.parent.remove_cell(idx)
674+
elif ev.modifiers() & QtCore.Qt.AltModifier:
675+
self.parent.merge_cells(idx)
673676
elif self.parent.masksOn and not self.parent.deleting_multiple:
674677
self.parent.unselect_cell()
675-
except Exception as err:
676-
print('Error encountered while drawing. Saving masks and exiting...')
677-
_save_sets(self.parent)
678-
raise(err)
679-
678+
self.parent.select_cell(idx)
679+
elif self.parent.deleting_multiple:
680+
if idx in self.parent.removing_cells_list:
681+
self.parent.unselect_cell_multi(idx)
682+
self.parent.removing_cells_list.remove(idx)
683+
else:
684+
self.parent.select_cell_multi(idx)
685+
self.parent.removing_cells_list.append(idx)
686+
elif self.parent.masksOn and not self.parent.deleting_multiple:
687+
self.parent.unselect_cell()
688+
689+
@unsilence_exceptions
680690
def mouseDragEvent(self, ev):
681691
ev.ignore()
682692
return
683693

694+
@unsilence_exceptions
684695
def hoverEvent(self, ev):
685696
if self.parent.in_stroke:
686697
if self.parent.in_stroke:
@@ -739,9 +750,11 @@ def end_stroke(self):
739750
self.parent.add_set()
740751
self.parent.in_stroke = False
741752

753+
@unsilence_exceptions
742754
def tabletEvent(self, ev):
743755
pass
744756

757+
@unsilence_exceptions
745758
def drawAt(self, pos, ev=None):
746759
mask = self.strokemask
747760
stroke = self.parent.current_stroke
@@ -786,6 +799,7 @@ def drawAt(self, pos, ev=None):
786799
stroke.append([self.parent.currentZ, x, y, iscent])
787800
self.updateImage()
788801

802+
@unsilence_exceptions
789803
def setDrawKernel(self, kernel_size=3):
790804
bs = kernel_size
791805
kernel = np.ones((bs, bs), np.uint8)

cellpose/io.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def logger_setup(cp_path=".cellpose", logfile_name="run.log", stdout_file_replac
9090
formatter = logging.Formatter("%(asctime)s [%(module)s %(levelname)s] %(message)s")
9191
debug_formatter = logging.Formatter("%(asctime)s %(levelname)s [%(filename)s:%(lineno)d - %(funcName)20s()] %(message)s")
9292
logger = logging.getLogger('cellpose')
93-
logger.setLevel(logging.INFO)
93+
logger.setLevel(logging.DEBUG)
9494
logger.handlers.clear()
9595

9696
logfile_fh.setFormatter(debug_formatter)

0 commit comments

Comments
 (0)