1
1
from enum import Enum
2
+ from threading import Thread
2
3
from typing import List
3
4
4
5
from magicgui .widgets import request_values
5
6
from napari import Viewer
7
+ from napari ._qt .qt_resources import QColoredSVGIcon
6
8
from napari .layers import Layer
7
9
from qtpy .QtCore import Qt
8
10
from qtpy .QtGui import QIcon , QPixmap
9
- from qtpy .QtWidgets import QMessageBox , QPushButton , QVBoxLayout , QWidget
11
+ from qtpy .QtWidgets import QHBoxLayout , QMessageBox , QPushButton , QWidget
10
12
11
13
from napari_imagej ._module_utils import _get_layers_hack
12
- from napari_imagej .setup_imagej import ij , jc , running_headless
14
+ from napari_imagej .setup_imagej import ensure_jvm_started , ij , jc , running_headless
13
15
14
16
15
17
class GUIWidget (QWidget ):
16
18
def __init__ (self , viewer : Viewer ):
17
19
super ().__init__ ()
18
- self .setLayout (QVBoxLayout ())
20
+ self .setLayout (QHBoxLayout ())
21
+
22
+ self .from_ij : FromIJButton = FromIJButton (viewer )
23
+ self .layout ().addWidget (self .from_ij )
24
+
25
+ self .to_ij : ToIJButton = ToIJButton (viewer )
26
+ self .layout ().addWidget (self .to_ij )
19
27
20
28
self .gui_button : GUIButton = GUIButton ()
21
29
self .layout ().addWidget (self .gui_button )
22
30
23
- self .to_ij : ToIJButton = ToIJButton ()
24
- self .layout ().addWidget (self .to_ij )
31
+ if running_headless ():
32
+ self .gui_button .clicked .connect (self .gui_button .disable_popup )
33
+ else :
34
+ self .gui_button .clicked .connect (self ._showUI )
35
+ self .gui_button .clicked .connect (lambda : self .to_ij .setEnabled (True ))
36
+ self .gui_button .clicked .connect (lambda : self .from_ij .setEnabled (True ))
25
37
26
- self .from_ij : FromIJButton = FromIJButton (viewer )
27
- self .layout ().addWidget (self .from_ij )
28
- if not running_headless ():
29
- self .gui_button .clicked .connect (lambda : self .to_ij .setHidden (False ))
30
- self .gui_button .clicked .connect (lambda : self .from_ij .setHidden (False ))
38
+ def _showUI (self ):
39
+ """
40
+ NB: This must be its own function to prevent premature calling of ij()
41
+ """
42
+ ensure_jvm_started ()
43
+ ij ().ui ().showUI ()
31
44
32
45
33
46
class ToIJButton (QPushButton ):
34
- def __init__ (self ):
47
+ def __init__ (self , viewer ):
35
48
super ().__init__ ()
36
- self .setHidden (True )
37
- self .setText ("Send layers to ImageJ2" )
49
+ self .setEnabled (False )
50
+ icon = QColoredSVGIcon .from_resources ("long_right_arrow" )
51
+ self .setIcon (icon .colored (theme = viewer .theme ))
52
+ self .setToolTip ("Send layers to ImageJ2" )
38
53
self .clicked .connect (self .send_layers )
39
54
55
+ def _set_icon (self , path : str ):
56
+ icon : QIcon = QIcon (QPixmap (path ))
57
+ self .setIcon (icon )
58
+
40
59
def send_layers (self ):
41
60
layers : dict = request_values (
42
61
title = "Send layers to ImageJ2" ,
@@ -55,10 +74,16 @@ def __init__(self, viewer: Viewer):
55
74
super ().__init__ ()
56
75
self .viewer = viewer
57
76
58
- self .setHidden (True )
59
- self .setText ("Get layers from ImageJ2" )
77
+ self .setEnabled (False )
78
+ icon = QColoredSVGIcon .from_resources ("long_left_arrow" )
79
+ self .setIcon (icon .colored (theme = viewer .theme ))
80
+ self .setToolTip ("Get layers from ImageJ2" )
60
81
self .clicked .connect (self .get_layers )
61
82
83
+ def _set_icon (self , path : str ):
84
+ icon : QIcon = QIcon (QPixmap (path ))
85
+ self .setIcon (icon )
86
+
62
87
def _get_objects (self , t ):
63
88
compatibleInputs = ij ().convert ().getCompatibleInputs (t )
64
89
compatibleInputs .addAll (ij ().object ().getObjects (t ))
@@ -87,28 +112,30 @@ def get_layers(self) -> List[Layer]:
87
112
class GUIButton (QPushButton ):
88
113
def __init__ (self ):
89
114
super ().__init__ ()
90
- self ._text = "Display ImageJ2 GUI"
91
-
92
- if running_headless ():
93
- self ._setup_headless ()
94
- else :
115
+ running_headful = not running_headless ()
116
+ self .setEnabled (False )
117
+ if running_headful :
95
118
self ._setup_headful ()
119
+ else :
120
+ self ._setup_headless ()
96
121
97
122
def _set_icon (self , path : str ):
98
123
icon : QIcon = QIcon (QPixmap (path ))
99
124
self .setIcon (icon )
100
125
101
126
def _setup_headful (self ):
102
- self ._set_icon ("resources/16x16-flat.png" )
103
- self .setText (self ._text )
104
- self .setToolTip ("Open ImageJ2 in a new window!" )
105
- self .clicked .connect (ij ().ui ().showUI )
127
+ self ._set_icon ("resources/16x16-flat-disabled.png" )
128
+ self .setToolTip ("Display ImageJ2 GUI (loading)" )
129
+ def post_setup ():
130
+ ensure_jvm_started ()
131
+ self ._set_icon ("resources/16x16-flat.png" )
132
+ self .setEnabled (True )
133
+ self .setToolTip ("Display ImageJ2 GUI" )
134
+ Thread (target = post_setup ).start ()
106
135
107
136
def _setup_headless (self ):
108
137
self ._set_icon ("resources/16x16-flat-disabled.png" )
109
- self .setText (self ._text + " (disabled)" )
110
- self .setToolTip ("Not available when running PyImageJ headlessly!" )
111
- self .clicked .connect (self .disable_popup )
138
+ self .setToolTip ("ImageJ2 GUI unavailable!" )
112
139
113
140
def disable_popup (self ):
114
141
msg : QMessageBox = QMessageBox ()
0 commit comments