|
1 | 1 | """ |
2 | 2 | Copyright © 2025 Howard Hughes Medical Institute, Authored by Carsen Stringer , Michael Rariden and Marius Pachitariu. |
3 | 3 | """ |
| 4 | +import logging |
| 5 | +import traceback |
4 | 6 | from qtpy import QtGui, QtCore |
5 | 7 | from qtpy.QtGui import QPixmap, QDoubleValidator |
6 | 8 | from qtpy.QtWidgets import QWidget, QDialog, QGridLayout, QPushButton, QLabel, QLineEdit, QDialogButtonBox, QComboBox, QCheckBox, QVBoxLayout |
@@ -135,6 +137,16 @@ def setup(self): |
135 | 137 |
|
136 | 138 | # return ChannelChoose, ChannelLabels |
137 | 139 |
|
| 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 |
138 | 150 |
|
139 | 151 | class ModelButton(QPushButton): |
140 | 152 |
|
@@ -582,6 +594,7 @@ def __init__(self, parent=None, border=None, lockAspect=False, enableMouse=True, |
582 | 594 | self.parent = parent |
583 | 595 | self.axHistoryPointer = -1 |
584 | 596 |
|
| 597 | + @unsilence_exceptions |
585 | 598 | def keyPressEvent(self, ev): |
586 | 599 | """ |
587 | 600 | 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): |
629 | 642 | self.parent.current_stroke = [] |
630 | 643 | self.parent.in_stroke = False |
631 | 644 |
|
| 645 | + @unsilence_exceptions |
632 | 646 | def mouseClickEvent(self, ev): |
633 | 647 | if not (self.parent.masksOn or |
634 | 648 | self.parent.outlinesOn) and self.parent.removing_region: |
635 | 649 | return |
636 | 650 |
|
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) |
673 | 676 | elif self.parent.masksOn and not self.parent.deleting_multiple: |
674 | 677 | 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 |
680 | 690 | def mouseDragEvent(self, ev): |
681 | 691 | ev.ignore() |
682 | 692 | return |
683 | 693 |
|
| 694 | + @unsilence_exceptions |
684 | 695 | def hoverEvent(self, ev): |
685 | 696 | if self.parent.in_stroke: |
686 | 697 | if self.parent.in_stroke: |
@@ -739,9 +750,11 @@ def end_stroke(self): |
739 | 750 | self.parent.add_set() |
740 | 751 | self.parent.in_stroke = False |
741 | 752 |
|
| 753 | + @unsilence_exceptions |
742 | 754 | def tabletEvent(self, ev): |
743 | 755 | pass |
744 | 756 |
|
| 757 | + @unsilence_exceptions |
745 | 758 | def drawAt(self, pos, ev=None): |
746 | 759 | mask = self.strokemask |
747 | 760 | stroke = self.parent.current_stroke |
@@ -786,6 +799,7 @@ def drawAt(self, pos, ev=None): |
786 | 799 | stroke.append([self.parent.currentZ, x, y, iscent]) |
787 | 800 | self.updateImage() |
788 | 801 |
|
| 802 | + @unsilence_exceptions |
789 | 803 | def setDrawKernel(self, kernel_size=3): |
790 | 804 | bs = kernel_size |
791 | 805 | kernel = np.ones((bs, bs), np.uint8) |
|
0 commit comments