Repository: napari/napari

Issue:
PermissionError upon napari.view_image()
```
>>> v = napari.view_image(h)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/site-packages/napari/view_layers.py", line 134, in view_image
    return _make_viewer_then('add_image', args, kwargs)
  File "/usr/lib/python3.8/site-packages/napari/view_layers.py", line 115, in _make_viewer_then
    viewer = Viewer(**vkwargs)
  File "/usr/lib/python3.8/site-packages/napari/viewer.py", line 52, in __init__
    self._window = Window(self, show=show)
  File "/usr/lib/python3.8/site-packages/napari/_qt/qt_main_window.py", line 360, in __init__
    get_app()
  File "/usr/lib/python3.8/site-packages/napari/_qt/qt_event_loop.py", line 182, in get_app
    _register_napari_resources()
  File "/usr/lib/python3.8/site-packages/napari/_qt/qt_resources/_icons.py", line 359, in _register_napari_resources
    resources = _compile_napari_resources(save_path=persist and save_path)
  File "/usr/lib/python3.8/site-packages/napari/_qt/qt_resources/_icons.py", line 321, in _compile_napari_resources
    Path(save_path).write_bytes(output)
  File "/usr/lib/python3.8/pathlib.py", line 1241, in write_bytes
    with self.open(mode='wb') as f:
  File "/usr/lib/python3.8/pathlib.py", line 1218, in open
    return io.open(self, mode, buffering, encoding, errors, newline,
  File "/usr/lib/python3.8/pathlib.py", line 1074, in _opener
    return self._accessor.open(self, flags, mode)
PermissionError: [Errno 13] Permission denied: '/usr/lib/python3.8/site-packages/napari/_qt/qt_resources/_qt_resources_PyQt5_5_14_2_9fb95879ef4c41b7750c685ae3465e22.py'
```
I'm trying to visualize a pandas dataframe of images, but I'm getting this `PermissionError`.


Discussion:
I suppose this is a problem of not having write access in a system location. Not sure why this is being done, and how to overcome this.
ahhh, i did wonder if we were ever going to run into this...
What's happening here is that napari needs to compile icons for the GUI to use, and it tries to save those (to the directory where napari is installed) so they don't need to be recompiled every time you start the program.

It looks like you're using your global system python (instead of a virtual environment, for example), hence the error.  (I'm curious, did you have to run `sudo pip install` to get it there in the first place?)

we can definitely wrap that `Path(save_path).write_bytes(output)` line in a try/except so that you don't get an exception (but do note that your launch time will be slightly longer as a result of having napari in a non-writeable area...)

Until we catch that error on our side, you'll need to either 1) install into a non-protected area like a conda environment, or 2) directly edit line 321 in `/usr/lib/python3.8/site-packages/napari/_qt/qt_resources/_icons.py` as follows:

```python
            try:
                Path(save_path).write_bytes(output)
            except Exception:
                pass
```
yes, I'm using the system python in this case. I'll edit the line directly for now! thanks for the response.

Resolving patch:
diff --git a/napari/_qt/qt_resources/_icons.py b/napari/_qt/qt_resources/_icons.py
--- a/napari/_qt/qt_resources/_icons.py
+++ b/napari/_qt/qt_resources/_icons.py
@@ -37,6 +37,8 @@
 
 import qtpy
 
+from ...utils.translations import trans
+
 __all__ = [
     '_register_napari_resources',
     'compile_qt_svgs',
@@ -318,7 +320,18 @@ def _compile_napari_resources(
     with _temporary_qrc_file(svgs, prefix='themes') as qrc:
         output = compile_qrc(qrc)
         if save_path:
-            Path(save_path).write_bytes(output)
+            try:
+                Path(save_path).write_bytes(output)
+            except OSError as e:
+                import warnings
+
+                msg = trans._(
+                    "Unable to save qt-resources: {err}",
+                    err=str(e),
+                    deferred=True,
+                )
+                warnings.warn(msg)
+
         return output.decode()
 
 


Test patch: