Skip to content

Instantly share code, notes, and snippets.

@alisterburt
Created September 7, 2021 10:28
Show Gist options
  • Select an option

  • Save alisterburt/9607ac7b84bec94afc06ed7b93aacbc9 to your computer and use it in GitHub Desktop.

Select an option

Save alisterburt/9607ac7b84bec94afc06ed7b93aacbc9 to your computer and use it in GitHub Desktop.
napari selectable evented list example
import napari
from napari.utils.events import SelectableEventedList
from napari._qt.containers import QtListView, QtListModel
from qtpy.QtCore import Qt, QModelIndex, QSize
from qtpy.QtGui import QImage
import numpy as np
# simple object for our genes
class MyGene:
def __init__(self, name):
self.name = name
# Model class is an interface between our data and Qt,
# Qt uses this to see what it should render when certain 'roles'
# are requested.
# https://doc.qt.io/qt-5/model-view-programming.html#model-classes
class MyGeneModel(QtListModel):
def __init__(self, root: SelectableEventedList[MyGene]):
super().__init__(root)
def data(self, index: QModelIndex, role: Qt.ItemDataRole):
"""Return data at `index` for the requested `role`.
see https://doc.qt.io/qt-5/model-view-programming.html#item-roles
"""
if role == Qt.DisplayRole: # displayed text
# this is how you access your MyGene object
my_gene = index.data(Qt.UserRole)
return my_gene.name
if role == Qt.EditRole:
return 'edit me'
if role == Qt.DecorationRole: # thumbnail image
return QImage(
np.random.random((32, 32, 4)),
32,
32,
QImage.Format_RGBA8888,
)
if role == Qt.SizeHintRole: # determines size of item
return QSize(64, 34)
return super().data(index, role)
def setData(self, index: QModelIndex, value, role: Qt.ItemDataRole) -> bool:
"""Set data at `index` for `role` to `value`."""
if value and role == Qt.EditRole:
# User has double-clicked on the item name
my_object = index.data(Qt.UserRole)
my_object.name = value
return super().setData(index, value, role=role)
class MyGeneListView(QtListView):
def __init__(self, root, parent=None):
super().__init__(root=root, parent=parent)
self.setModel(MyGeneModel(root))
# set up napari viewer
viewer = napari.Viewer()
# list of placeholder genes as an example
gene_list = [MyGene(f'gene {i}') for i in range(3)]
selectable_evented_gene_list = SelectableEventedList(gene_list)
# example function which will fire on selection change
def on_selection_change(event=None):
print('selection changed!')
viewer.add_image(np.random.random((28, 28)))
selectable_evented_gene_list.selection.events.active.connect(
on_selection_change
)
# create widget from SelectableEventedList and add to viewer
my_list_widget = MyGeneListView(selectable_evented_gene_list)
viewer.window.add_dock_widget(my_list_widget)
napari.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment