# Buggy code
def __init__(self, viewer):
    super().__init__()
    self.setAttribute(Qt.WA_DeleteOnClose)
    self.pool = QThreadPool()

    QCoreApplication.setAttribute(Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)

    self.viewer = viewer
    self.dims = QtDims(self.viewer.dims)
    self.controls = QtControls(self.viewer)
    self.layers = QtLayerList(self.viewer.layers)
    self.layerButtons = QtLayerButtons(self.viewer)
    self.viewerButtons = QtViewerButtons(self.viewer)
    self._console = None

    layerList = QWidget()
    layerList.setObjectName("layerList")
    layerListLayout = QVBoxLayout()
    layerListLayout.addWidget(self.layerButtons)
    layerListLayout.addWidget(self.layers)
    layerListLayout.addWidget(self.viewerButtons)
    layerListLayout.setContentsMargins(8, 4, 8, 6)
    layerList.setLayout(layerListLayout)
    self.dockLayerList = QtViewerDockWidget(
        self,
        layerList,
        name="layer list",
        area="left",
        allowed_areas=["left", "right"],
    )
    self.dockLayerControls = QtViewerDockWidget(
        self,
        self.controls,
        name="layer controls",
        area="left",
        allowed_areas=["left", "right"],
    )
    self.dockConsole = QtViewerDockWidget(
        self,
        QWidget(),
        name="console",
        area="bottom",
        allowed_areas=["top", "bottom"],
        shortcut="Ctrl+Shift+C",
    )
    self.dockConsole.setVisible(False)
    self.dockLayerControls.visibilityChanged.connect(self._constrain_width)
    self.dockLayerList.setMaximumWidth(258)
    self.dockLayerList.setMinimumWidth(258)

    # This dictionary holds the corresponding vispy visual for each layer
    self.layer_to_visual = {}
    self.viewerButtons.consoleButton.clicked.connect(self.toggle_console_visibility)

    self.canvas = SceneCanvas(keys=None, vsync=True, parent=self)
    self.canvas.events.ignore_callback_errors = False
    self.canvas.events.draw.connect(self.dims.enable_play)
    self.canvas.native.setMinimumSize(QSize(200, 200))
    self.canvas.context.set_depth_func("lequal")

    self.canvas.connect(self.on_mouse_move)
    self.canvas.connect(self.on_mouse_press)
    self.canvas.connect(self.on_mouse_release)
    self.canvas.connect(self.on_key_press)
    self.canvas.connect(self.on_key_release)
    self.canvas.connect(self.on_draw)

    self.view = self.canvas.central_widget.add_view()
    self._update_camera()

    main_widget = QWidget()
    main_layout = QVBoxLayout()
    main_layout.setContentsMargins(10, 22, 10, 2)
    main_layout.addWidget(self.canvas.native)
    main_layout.addWidget(self.dims)
    main_layout.setSpacing(10)
    main_widget.setLayout(main_layout)

    self.setOrientation(Qt.Vertical)
    self.addWidget(main_widget)

    self._last_visited_dir = str(Path.home())

    self._cursors = {
        "cross": Qt.CrossCursor,
        "forbidden": Qt.ForbiddenCursor,
        "pointing": Qt.PointingHandCursor,
        "standard": QCursor(),
    }

    self._update_palette(None)

    self.viewer.events.interactive.connect(self._on_interactive)
    self.viewer.events.cursor.connect(self._on_cursor)
    self.viewer.events.reset_view.connect(self._on_reset_view)
    self.viewer.events.palette.connect(self._update_palette)
    self.viewer.layers.events.reordered.connect(self._reorder_layers)
    self.viewer.layers.events.added.connect(self._add_layer)
    self.viewer.layers.events.removed.connect(self._remove_layer)
    self.viewer.dims.events.camera.connect(lambda event: self._update_camera())
    # stop any animations whenever the layers change
    self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

    self.setAcceptDrops(True)


# Traceback (AttributeError)
Traceback (most recent call last):
File "/Users/gbokota/Documents/projekty/napari/napari/components/viewer_model.py", line 418, in _toggle_theme
self.theme = theme_names[(cur_theme + 1) % len(theme_names)]
File "/Users/gbokota/Documents/projekty/napari/napari/components/viewer_model.py", line 130, in theme
self.palette = self.themes[theme]
File "/Users/gbokota/Documents/projekty/napari/napari/components/viewer_model.py", line 114, in palette
self.events.palette()
File "/Users/gbokota/Documents/projekty/napari/napari/utils/event.py", line 508, in __call__
self._invoke_callback(cb, event)
File "/Users/gbokota/Documents/projekty/napari/napari/utils/event.py", line 529, in _invoke_callback
cb_event=(cb, event),
File "/Users/gbokota/Documents/projekty/napari/napari/utils/event.py", line 523, in _invoke_callback
cb(event)
File "/Users/gbokota/Documents/projekty/napari/napari/_qt/qt_main_window.py", line 99, in <lambda>
lambda event: self._update_palette(event.palette)
AttributeError: 'Event' object has no attribute 'palette'

# Fixed code
def __init__(self, viewer):
    super().__init__()
    self.setAttribute(Qt.WA_DeleteOnClose)
    self.pool = QThreadPool()

    QCoreApplication.setAttribute(Qt.AA_UseStyleSheetPropagationInWidgetStyles, True)

    self.viewer = viewer
    self.dims = QtDims(self.viewer.dims)
    self.controls = QtControls(self.viewer)
    self.layers = QtLayerList(self.viewer.layers)
    self.layerButtons = QtLayerButtons(self.viewer)
    self.viewerButtons = QtViewerButtons(self.viewer)
    self._console = None

    layerList = QWidget()
    layerList.setObjectName("layerList")
    layerListLayout = QVBoxLayout()
    layerListLayout.addWidget(self.layerButtons)
    layerListLayout.addWidget(self.layers)
    layerListLayout.addWidget(self.viewerButtons)
    layerListLayout.setContentsMargins(8, 4, 8, 6)
    layerList.setLayout(layerListLayout)
    self.dockLayerList = QtViewerDockWidget(
        self,
        layerList,
        name="layer list",
        area="left",
        allowed_areas=["left", "right"],
    )
    self.dockLayerControls = QtViewerDockWidget(
        self,
        self.controls,
        name="layer controls",
        area="left",
        allowed_areas=["left", "right"],
    )
    self.dockConsole = QtViewerDockWidget(
        self,
        QWidget(),
        name="console",
        area="bottom",
        allowed_areas=["top", "bottom"],
        shortcut="Ctrl+Shift+C",
    )
    self.dockConsole.setVisible(False)
    # because the console is loaded lazily in the @getter, this line just
    # gets (or creates) the console when the dock console is made visible.
    self.dockConsole.visibilityChanged.connect(
        lambda visible: self.console if visible else None
    )
    self.dockLayerControls.visibilityChanged.connect(self._constrain_width)
    self.dockLayerList.setMaximumWidth(258)
    self.dockLayerList.setMinimumWidth(258)

    # This dictionary holds the corresponding vispy visual for each layer
    self.layer_to_visual = {}
    self.viewerButtons.consoleButton.clicked.connect(self.toggle_console_visibility)

    self.canvas = SceneCanvas(keys=None, vsync=True, parent=self)
    self.canvas.events.ignore_callback_errors = False
    self.canvas.events.draw.connect(self.dims.enable_play)
    self.canvas.native.setMinimumSize(QSize(200, 200))
    self.canvas.context.set_depth_func("lequal")

    self.canvas.connect(self.on_mouse_move)
    self.canvas.connect(self.on_mouse_press)
    self.canvas.connect(self.on_mouse_release)
    self.canvas.connect(self.on_key_press)
    self.canvas.connect(self.on_key_release)
    self.canvas.connect(self.on_draw)

    self.view = self.canvas.central_widget.add_view()
    self._update_camera()

    main_widget = QWidget()
    main_layout = QVBoxLayout()
    main_layout.setContentsMargins(10, 22, 10, 2)
    main_layout.addWidget(self.canvas.native)
    main_layout.addWidget(self.dims)
    main_layout.setSpacing(10)
    main_widget.setLayout(main_layout)

    self.setOrientation(Qt.Vertical)
    self.addWidget(main_widget)

    self._last_visited_dir = str(Path.home())

    self._cursors = {
        "cross": Qt.CrossCursor,
        "forbidden": Qt.ForbiddenCursor,
        "pointing": Qt.PointingHandCursor,
        "standard": QCursor(),
    }

    self._update_palette()

    self.viewer.events.interactive.connect(self._on_interactive)
    self.viewer.events.cursor.connect(self._on_cursor)
    self.viewer.events.reset_view.connect(self._on_reset_view)
    self.viewer.events.palette.connect(self._update_palette)
    self.viewer.layers.events.reordered.connect(self._reorder_layers)
    self.viewer.layers.events.added.connect(self._add_layer)
    self.viewer.layers.events.removed.connect(self._remove_layer)
    self.viewer.dims.events.camera.connect(lambda event: self._update_camera())
    # stop any animations whenever the layers change
    self.viewer.events.layers_change.connect(lambda x: self.dims.stop())

    self.setAcceptDrops(True)