mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 05:44:52 +00:00
Python: Initial support for implementing models in Python
This provides a Model base class in Python and sub-classes of that can be set as data models in slint. The ListModel is provided as basic sub-class operating on a list() and allowing mutation and notifying the view on the Slint side. Similarly, an array declared in Slint is exposed as an object to Python that looks like a Model. Both support the sequence protocol. Fixes #4135
This commit is contained in:
parent
82d784a4d4
commit
2f313f84ec
6 changed files with 393 additions and 1 deletions
|
@ -14,3 +14,4 @@ def load_file(path):
|
|||
Image = native.PyImage
|
||||
Color = native.PyColor
|
||||
Brush = native.PyBrush
|
||||
Model = native.PyModelBase
|
||||
|
|
71
api/python/slint/models.py
Normal file
71
api/python/slint/models.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
# Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
from . import slint as native
|
||||
|
||||
|
||||
class Model(native.PyModelBase):
|
||||
def __new__(cls, *args):
|
||||
return super().__new__(cls)
|
||||
|
||||
def __init__(self, lst=None):
|
||||
self.init_self(self)
|
||||
|
||||
def __len__(self):
|
||||
return self.row_count()
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.row_data(index)
|
||||
|
||||
def __setitem__(self, index, value):
|
||||
self.set_row_data(index, value)
|
||||
|
||||
def __iter__(self):
|
||||
return ModelIterator(self)
|
||||
|
||||
|
||||
class ListModel(Model):
|
||||
def __init__(self, lst=None):
|
||||
super().__init__()
|
||||
self.list = lst or []
|
||||
|
||||
def row_count(self):
|
||||
return len(self.list)
|
||||
|
||||
def row_data(self, row):
|
||||
return self.list[row]
|
||||
|
||||
def set_row_data(self, row, data):
|
||||
self.list[row] = data
|
||||
super().notify_row_changed(row)
|
||||
|
||||
def __delitem__(self, key):
|
||||
if isinstance(key, slice):
|
||||
start, stop, step = key.indices(len(self.list))
|
||||
del self.list[key]
|
||||
count = len(range(start, stop, step))
|
||||
super().notify_row_removed(start, count)
|
||||
else:
|
||||
del self.list[key]
|
||||
super().notify_row_removed(key, 1)
|
||||
|
||||
def append(self, value):
|
||||
index = len(self.list)
|
||||
self.list.append(value)
|
||||
super().notify_row_added(index, 1)
|
||||
|
||||
|
||||
class ModelIterator:
|
||||
def __init__(self, model):
|
||||
self.model = model
|
||||
self.index = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.index >= self.model.row_count():
|
||||
raise StopIteration()
|
||||
index = self.index
|
||||
self.index += 1
|
||||
return self.model.row_data(index)
|
Loading…
Add table
Add a link
Reference in a new issue