---
# System prepended metadata

title: 'QtViewer is created:'

---

# napari rendering backend abstraction

## startup
0. viewer model -> window created
1. QtViewer is created: https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_main_window.py#L117C29-L117C29
    - [canvas class can be passed](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L178)
    - canvas object is instantiated in QtViewer [here](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L207-L213)


## canvas class

example implementation: https://github.com/napari/napari/blob/main/napari/_vispy/canvas.py#L55

Required properties:
- layer_to_visual


Required methods:
- [`_add_layer`](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L632-L654): called to add a layer to the scene by QtViewer ([here](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L265) and [here](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L630)). This method 
- `screenshot`: returns an image of the scene. used by QtViewer [here](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L747).
- [`_scene_canvas._backend._keyEvent`](https://github.com/napari/napari/blob/2748e226f4e46539fcfcab0bf552ce26f7848543/napari/_qt/qt_viewer.py#L974C9-L976C10): propogates events from the Qt events to the vispy events. we likely want to update the events so that we aren't depending on backened events so heavily. for now, we could add a method on the canvas class to handle events from Qt.


## Adding layers to the viewer
The process through which napari adds layers to the scene

1. user calls [viewer.add_image()](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/components/viewer_model.py#L699). The layer class is [constructed](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/components/viewer_model.py#L943) and [added to the layer list](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/components/viewer_model.py#L945).
2. The layer list has a [callback](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/components/viewer_model.py#L263) that gets called when a layer is added to the list. [Callback function](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/components/viewer_model.py#L567-L600).
3. The layer list event also triggers the `_add_layer` method on the QtViewer ([here](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/_qt/qt_viewer.py#L621)) which is where the visual is [created](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/_qt/qt_viewer.py#L640C29-L640C29) and added to the scene.
([here](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/_qt/qt_viewer.py#L654C21-L654C45)).
4.The Canvas class creates the visual and adds to the scene [vispy implementation](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/_vispy/canvas.py#L551-L572_)


## To do

1. create FastplotlibImageLayer class
    - in the __init__
        - create the image graphic and store it on the class
        - store the layer as self.layer
        - call the _on_data_change() method
    - implement the _on_data_change() method
        - takes data from `self.layer._data_view` ([vispy implementation](https://github.com/napari/napari/blob/08a22b053f87ca5010fe43b983390c199921f83e/napari/_vispy/layers/image.py#L123C31-L123C53))
        - puts it into the graphic



