Browse Source

chore(table): add support for enum type (#548)

pull/469/head^2
Pier CeccoPierangioliEugenio 3 months ago committed by GitHub
parent
commit
003344e080
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 30
      libs/pyTermTk/TermTk/TTkWidgets/TTkModelView/table_edit_proxy.py
  2. 0
      tests/t.ui/test.ui.032.table.14.list.01.item.py
  3. 96
      tests/t.ui/test.ui.032.table.14.list.02.custom.py
  4. 141
      tests/t.ui/test.ui.032.table.15.test.clipboard.py

30
libs/pyTermTk/TermTk/TTkWidgets/TTkModelView/table_edit_proxy.py

@ -359,10 +359,6 @@ class _BoolListProxy(_ListBaseProxy):
Specialized list proxy that presents True/False choices for boolean cell values.
Displays as a compact 2-item list.
'''
def __init__(self, **kwargs):
''' Initialize the boolean list proxy
'''
super().__init__(**kwargs|{'size':(7,4), 'layout':TTkGridLayout()})
@pyTTkSlot(TTkAbstractListItem)
def _itemClicked(self, item:TTkAbstractListItem):
@ -397,6 +393,29 @@ class _BoolListProxy(_ListBaseProxy):
'''
return self._list.selectedItems()[0].data()
class _EnumListProxy(_BoolListProxy):
''' Enum editor for table cells
Specialized list proxy that presents choices for enum cell values.
'''
@staticmethod
def editWidgetFactory(data: Any) -> TTkTableProxyEditWidget:
''' Factory method to create a enum editor from enum data
:param data: The initial enum value
:type data: Enum
:return: A new enum list proxy instance
:rtype: :py:class:`TTkTableProxyEditWidget`
:raises ValueError: If data is not a enum
'''
if not isinstance(data, Enum):
raise ValueError(f"{data} is not an Enum")
items = list(type(data))
value = TTkCellListType(value=data, items=items)
sb = _BoolListProxy(value=value, items=items)
return sb
class _TextEditViewProxy(TTkTextEditView, TTkTableProxyEditWidget):
''' Text editor view for table cells
@ -996,8 +1015,9 @@ class TTkTableProxyEdit():
Proxies are checked in order, with custom proxies taking precedence.
'''
self._proxies = [
TTkProxyEditDef(class_def=_ListBaseProxy, types=(TTkCellListTypeBase)),
TTkProxyEditDef(class_def=_ListBaseProxy, types=(TTkCellListTypeBase)),
TTkProxyEditDef(class_def=_BoolListProxy, types=(bool)),
TTkProxyEditDef(class_def=_EnumListProxy, types=(Enum)),
TTkProxyEditDef(class_def=_SpinBoxProxy, types=(int, float)),
TTkProxyEditDef(class_def=_TextEditProxy, types=(str,)),
TTkProxyEditDef(class_def=_TextEditProxy, types=(TTkString,), flags=TTkTableProxyEditFlag.BASE),

0
tests/t.ui/test.ui.032.table.15.list.item.py → tests/t.ui/test.ui.032.table.14.list.01.item.py

96
tests/t.ui/test.ui.032.table.14.list.02.custom.py

@ -0,0 +1,96 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Demo inspired from:
# https://www.daniweb.com/programming/software-development/code/447834/applying-pyside-s-qabstracttablemodel
import os
import sys
import argparse
import random
from enum import Enum
from random import choice
from enum import Enum, auto
from typing import Tuple
sys.path.append(os.path.join(sys.path[0],'../..'))
import TermTk as ttk
parser = argparse.ArgumentParser()
parser.add_argument('-f', help='Full Screen (default)', action='store_true')
parser.add_argument('-w', help='Windowed', action='store_true')
args = parser.parse_args()
fullScreen = not args.w
mouseTrack = True
class MyEnum(Enum):
Foo=auto()
Bar=auto()
Baz=auto()
def __str__(self):
return self.name
class MyEnumYesNo(Enum):
Yes=True
No=False
def __str__(self):
return self.name
def __bool__(self):
return self.value
data = [
[
bool(random.randint(0,1)),
MyEnum.Foo,
MyEnum.Bar,
MyEnum.Baz,
MyEnumYesNo.Yes,
MyEnumYesNo.No,
random.choice(list(MyEnum)),
random.choice(list(MyEnumYesNo)),
] for y in range(20)
]
root = ttk.TTk(
title="pyTermTk Table Demo",
mouseTrack=mouseTrack)
if fullScreen:
rootTable = root
root.setLayout(ttk.TTkGridLayout())
else:
rootTable = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,40), title="Test Table 1", layout=ttk.TTkGridLayout(), border=True)
table_model = ttk.TTkTableModelList(data=data)
table = ttk.TTkTable(parent=rootTable, tableModel=table_model)
table.resizeRowsToContents()
table.resizeColumnsToContents()
root.mainloop()

141
tests/t.ui/test.ui.032.table.15.test.clipboard.py

@ -0,0 +1,141 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2025 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import sys
import argparse
import random
import datetime
from enum import Enum
from random import choice
from enum import Enum, auto
from typing import Tuple
sys.path.append(os.path.join(sys.path[0],'../..'))
import TermTk as ttk
parser = argparse.ArgumentParser()
parser.add_argument('-f', help='Full Screen (default)', action='store_true')
parser.add_argument('-w', help='Windowed', action='store_true')
args = parser.parse_args()
fullScreen = not args.w
mouseTrack = True
# Random date between two dates
def random_date(start_date, end_date):
time_between = end_date - start_date
days_between = time_between.days
random_days = random.randrange(days_between)
return start_date + datetime.timedelta(days=random_days)
# Random time
def random_time():
hour = random.randint(0, 23)
minute = random.randint(0, 59)
second = random.randint(0, 59)
return datetime.time(hour, minute, second)
# Random datetime
def random_datetime(start_datetime, end_datetime):
time_between = end_datetime - start_datetime
total_seconds = int(time_between.total_seconds())
random_seconds = random.randrange(total_seconds)
return start_datetime + datetime.timedelta(seconds=random_seconds)
class MyEnum(Enum):
Foo=auto()
Bar=auto()
Baz=auto()
def __str__(self):
return self.name
class MyEnumYesNo(Enum):
Yes=True
No=False
def __str__(self):
return self.name
def __bool__(self):
return self.value
data_list = [
'Pippo', 'Pluto', 'Paperino',
'Qui', 'Quo', 'Qua', # L'accento non ci va
'Minnie', 'Topolino'
]
data = [
[
bool(random.randint(0,1)),
'Pippo',
'Pluto',
ttk.TTkCellListType(value=random.choice(data_list), items=data_list)
] for y in range(20)
]
data = [
[
f"0x{random.randint(0,0xFFFF):04X}",
ttk.TTkString(f"0x{random.randint(0,0xFFFF):04X}", ttk.TTkColor.YELLOW),
bool(random.randint(0,1)),
ttk.TTkCellListType(value=random.choice(data_list), items=data_list),
random.choice(list(MyEnum)),
random.choice(list(MyEnumYesNo)),
random_time(),
random_date(datetime.date(2020,1,1), datetime.date(2025,12,31)),
random_datetime(datetime.datetime(2020,1,1), datetime.datetime(2025,12,31)),
] for y in range(20)
]
root = ttk.TTk(
title="pyTermTk Table Demo",
mouseTrack=mouseTrack,
sigmask=(
ttk.TTkTerm.Sigmask.CTRL_Z |
ttk.TTkTerm.Sigmask.CTRL_C ))
if fullScreen:
rootContainer = root
root.setLayout(ttk.TTkGridLayout())
else:
rootContainer = ttk.TTkWindow(parent=root,pos = (0,0), size=(150,40), title="Test Table 1", layout=ttk.TTkGridLayout(), border=True)
table_model = ttk.TTkTableModelList(data=data)
table = ttk.TTkTable(tableModel=table_model)
btn_quit = ttk.TTkButton(text='quit', maxSize=(8,3), border=True)
rootContainer.layout().addWidget(table,1,0,1,2)
rootContainer.layout().addWidget(btn_quit,0,0)
table.resizeRowsToContents()
table.resizeColumnsToContents()
btn_quit.clicked.connect(root.quit)
root.mainloop()
Loading…
Cancel
Save