Browse Source

chore: improve typing (#562)

pull/515/head^2
Pier CeccoPierangioliEugenio 3 months ago committed by GitHub
parent
commit
b066ee0ef3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 99
      libs/pyTermTk/TermTk/TTkAbstract/abstractscrollarea.py
  2. 291
      libs/pyTermTk/TermTk/TTkAbstract/abstractscrollview.py
  3. 13
      libs/pyTermTk/TermTk/TTkAbstract/abstracttablemodel.py
  4. 4
      libs/pyTermTk/TermTk/TTkCore/constant.py
  5. 6
      libs/pyTermTk/TermTk/TTkTestWidgets/tominspector.py
  6. 2
      libs/pyTermTk/TermTk/TTkWidgets/TTkModelView/tree.py
  7. 26
      libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/debugterminal.py
  8. 2
      tests/pytest/modelView/test_tablemodelcsv.py
  9. 2
      tests/pytest/modelView/test_tablemodellist.py

99
libs/pyTermTk/TermTk/TTkAbstract/abstractscrollarea.py

@ -23,7 +23,7 @@
__all__ = ['TTkAbstractScrollArea']
from dataclasses import dataclass
from typing import List,Any,Type
from typing import List,Any,Type,Optional
from TermTk.TTkCore.constant import TTkK
# from TermTk.TTkCore.log import TTkLog
@ -31,6 +31,7 @@ from TermTk.TTkCore.signal import pyTTkSlot
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.container import TTkContainer
from TermTk.TTkWidgets.scrollbar import TTkScrollBar
from TermTk.TTkLayouts.layout import TTkLayout
from TermTk.TTkLayouts.gridlayout import TTkGridLayout
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollViewInterface
@ -42,12 +43,25 @@ class _ForwardData():
methods: List[str]
class TTkAbstractScrollArea(TTkContainer):
'''
The :py:class:`TTkAbstractScrollArea` provides a scrolling area with on-demand scroll bars.
This abstract class manages vertical and horizontal scroll bars that appear automatically
based on the viewport size and content.
'''
__slots__ = (
'_processing', # this flag is required to avoid unnecessary loop on edge cases
'_viewport',
'_verticalScrollBar', '_verticalScrollBarPolicy',
'_horizontalScrollBar', '_horizontalScrollBarPolicy',)
_processing:bool
_viewport:Optional[TTkAbstractScrollViewInterface]
_verticalScrollBar:TTkScrollBar
_horizontalScrollBar:TTkScrollBar
_verticalScrollBarPolicy:TTkK.ScrollBarPolicy
_horizontalScrollBarPolicy:TTkK.ScrollBarPolicy
def __init__(self, *,
verticalScrollBarPolicy:TTkK.ScrollBarPolicy=TTkK.ScrollBarPolicy.ScrollBarAsNeeded,
horizontalScrollBarPolicy:TTkK.ScrollBarPolicy=TTkK.ScrollBarPolicy.ScrollBarAsNeeded,
@ -63,8 +77,10 @@ class TTkAbstractScrollArea(TTkContainer):
self.layout().addWidget(self._verticalScrollBar)
self.layout().addWidget(self._horizontalScrollBar)
def _resizeEvent(self):
if self._processing: return
def _resizeEvent(self) -> None:
''' Internal method to handle resize events and reposition scroll bars '''
if self._processing:
return
self._processing = True
w,h = self.size()
vert = 1 if self._verticalScrollBar.isVisible() else 0
@ -73,16 +89,24 @@ class TTkAbstractScrollArea(TTkContainer):
self._verticalScrollBar.setGeometry(w-1,0,1,h-hori)
if hori:
self._horizontalScrollBar.setGeometry(0,h-1,w-vert,1)
if self._viewport:
if isinstance(self._viewport, (TTkWidget, TTkLayout)):
self._viewport.setGeometry(0,0,w-vert,h-hori)
self._processing = False
def resizeEvent(self, w: int, h: int):
def resizeEvent(self, w: int, h: int) -> None:
''' Handle resize events
:param w: the new width
:type w: int
:param h: the new height
:type h: int
'''
self._resizeEvent()
@pyTTkSlot()
def _viewportChanged(self):
if not self.isVisible(): return
def _viewportChanged(self) -> None:
''' Internal slot to handle viewport changes and update scroll bar ranges and visibility '''
if not self._viewport or not self.isVisible(): return
w,h = self.size()
fw, fh = self._viewport.viewFullAreaSize()
dw, dh = self._viewport.viewDisplayedSize()
@ -125,16 +149,37 @@ class TTkAbstractScrollArea(TTkContainer):
self._resizeEvent()
@pyTTkSlot(int)
def _vscrollMoved(self, val):
def _vscrollMoved(self, val: int) -> None:
''' Internal slot to handle vertical scroll bar movement
:param val: the new vertical scroll position
:type val: int
'''
if not self._viewport:
return
ox, _ = self._viewport.getViewOffsets()
self._viewport.viewMoveTo(ox, val)
@pyTTkSlot(int)
def _hscrollMoved(self, val):
def _hscrollMoved(self, val: int) -> None:
''' Internal slot to handle horizontal scroll bar movement
:param val: the new horizontal scroll position
:type val: int
'''
if not self._viewport:
return
_, oy = self._viewport.getViewOffsets()
self._viewport.viewMoveTo(val, oy)
def setViewport(self, viewport):
def setViewport(self, viewport: TTkAbstractScrollViewInterface) -> None:
''' Set the viewport widget
:param viewport: the viewport widget implementing TTkAbstractScrollViewInterface
:type viewport: :py:class:`TTkAbstractScrollViewInterface`
:raises TypeError: if viewport does not implement TTkAbstractScrollViewInterface
'''
if not isinstance(viewport, TTkAbstractScrollViewInterface):
raise TypeError("TTkAbstractScrollViewInterface is required in TTkAbstractScrollArea.setVewport(viewport)")
if self._viewport:
@ -157,20 +202,44 @@ class TTkAbstractScrollArea(TTkContainer):
self.layout().addItem(viewport)
self._resizeEvent()
def setVerticalScrollBarPolicy(self, policy):
def setVerticalScrollBarPolicy(self, policy: TTkK.ScrollBarPolicy) -> None:
''' Set the vertical scroll bar policy
:param policy: the scroll bar policy (ScrollBarAsNeeded, ScrollBarAlwaysOn, ScrollBarAlwaysOff)
:type policy: :py:class:`TTkK.ScrollBarPolicy`
'''
if policy != self._verticalScrollBarPolicy:
self._verticalScrollBarPolicy = policy
self._viewportChanged()
def setHorizontalScrollBarPolicy(self, policy):
def setHorizontalScrollBarPolicy(self, policy: TTkK.ScrollBarPolicy) -> None:
''' Set the horizontal scroll bar policy
:param policy: the scroll bar policy (ScrollBarAsNeeded, ScrollBarAlwaysOn, ScrollBarAlwaysOff)
:type policy: :py:class:`TTkK.ScrollBarPolicy`
'''
if policy != self._horizontalScrollBarPolicy:
self._horizontalScrollBarPolicy = policy
self._viewportChanged()
def viewport(self) -> TTkAbstractScrollViewInterface:
def viewport(self) -> Optional[TTkAbstractScrollViewInterface]:
''' Return the current viewport
:return: the viewport widget or None
:rtype: :py:class:`TTkAbstractScrollViewInterface`, optional
'''
return self._viewport
def update(self, repaint=True, updateLayout=False, updateParent=False):
if self._viewport:
def update(self, repaint: bool = True, updateLayout: bool = False, updateParent: bool = False) -> None:
''' Update the scroll area and viewport
:param repaint: trigger a repaint, defaults to True
:type repaint: bool, optional
:param updateLayout: trigger a layout update, defaults to False
:type updateLayout: bool, optional
:param updateParent: trigger a parent update, defaults to False
:type updateParent: bool, optional
'''
if isinstance(self._viewport, (TTkWidget, TTkLayout)):
self._viewport.update(repaint, updateLayout, updateParent=False)
return super().update(repaint, updateLayout, updateParent)

291
libs/pyTermTk/TermTk/TTkAbstract/abstractscrollview.py

@ -20,7 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['TTkAbstractScrollViewInterface', 'TTkAbstractScrollView', 'TTkAbstractScrollViewGridLayout']
__all__ = ['TTkAbstractScrollViewInterface', 'TTkAbstractScrollView', 'TTkAbstractScrollViewLayout', 'TTkAbstractScrollViewGridLayout']
from typing import Tuple
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.cfg import TTkCfg
@ -46,10 +48,37 @@ class TTkAbstractScrollViewInterface():
* :py:class:`TTkAbstractScrollViewGridLayout`
'''
def __init__(self) -> None: pass
viewMovedTo:pyTTkSignal
'''
This signal is emitted when the view content move to a new position (x,y),
:param x: the new horizontal offset
:type x: int
:param y: the new vertical offset
:type y: int
'''
viewSizeChanged:pyTTkSignal
'''
This signal is emitted when the view content size changed
:param width: the new width
:type width: int
:param height: the new height
:type height: int
'''
viewChanged:pyTTkSignal
'''
This signal is emitted whenever there is a change in the view content topology (size,pos)
.. note:: This signal must be implemented in any implementation
of :py:class:`TTkAbstractScrollView` to notify that the view content boudaries changed
'''
def __init__(self) -> None:
pass
# Override this function
def viewFullAreaSize(self) -> tuple[int,int]:
def viewFullAreaSize(self) -> Tuple[int,int]:
'''
This method returns the full widget area size of the :py:class:`TTkAbstractScrollViewInterface` implementation.
@ -63,7 +92,7 @@ class TTkAbstractScrollViewInterface():
raise NotImplementedError()
# Override this function
def viewDisplayedSize(self) -> tuple[int,int]:
def viewDisplayedSize(self) -> Tuple[int,int]:
'''
This method returns the displayed size of the :py:class:`TTkAbstractScrollViewInterface` implementation.
@ -85,7 +114,7 @@ class TTkAbstractScrollViewInterface():
raise NotImplementedError()
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
def viewMoveTo(self, x: int, y: int) -> None:
'''
This method is used to set the vertical and horizontal offsets of the :py:class:`TTkAbstractScrollViewInterface`
@ -105,7 +134,7 @@ class TTkAbstractScrollViewInterface():
'''
raise NotImplementedError()
def getViewOffsets(self) -> tuple:
def getViewOffsets(self) -> Tuple[int,int]:
'''
Retrieve the vertical and horizontal offsets of the :py:class:`TTkAbstractScrollViewInterface`
@ -121,7 +150,7 @@ class TTkAbstractScrollViewInterface():
:return: the (x,y) offset
:rtype: tuple[int,int]
'''
return self._viewOffsetX, self._viewOffsetY
raise NotImplementedError()
class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
'''
@ -147,7 +176,7 @@ class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
:param width: the new width
:type width: int
:param height: the new heighht
:param height: the new height
:type height: int
'''
viewChanged:pyTTkSignal
@ -173,16 +202,33 @@ class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
# Do NOT use super()
TTkContainer.__init__(self, **kwargs)
def viewDisplayedSize(self) -> tuple[int,int]:
def viewDisplayedSize(self) -> Tuple[int,int]:
''' Return the displayed size of this view
:return: the (width, height) of the view
:rtype: tuple[int,int]
'''
return self.size()
def viewFullAreaSize(self) -> tuple[int,int]:
def viewFullAreaSize(self) -> Tuple[int,int]:
''' Return the full area size including padding
:return: the (width, height) of the full area
:rtype: tuple[int,int]
'''
t,b,l,r = self.getPadding()
_,_,w,h = self.layout().fullWidgetAreaGeometry()
return w+l+r, h+t+b
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
def viewMoveTo(self, x: int, y: int) -> None:
''' Move the view to the specified offset position
:param x: the horizontal offset
:type x: int
:param y: the vertical offset
:type y: int
'''
fw, fh = self.viewFullAreaSize()
dw, dh = self.viewDisplayedSize()
rangex = fw - dw
@ -191,8 +237,8 @@ class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
x = max(0,min(rangex,x))
y = max(0,min(rangey,y))
# TTkLog.debug(f"x:{x},y:{y}, wo:{self._viewOffsetX,self._viewOffsetY}")
if self._viewOffsetX == x and \
self._viewOffsetY == y: # Nothong to do
if ( self._viewOffsetX == x and
self._viewOffsetY == y ): # Nothing to do
return
self._viewOffsetX = x
self._viewOffsetY = y
@ -200,10 +246,15 @@ class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
self.viewChanged.emit()
self.update()
def getViewOffsets(self) -> tuple:
return self._viewOffsetX, self._viewOffsetY
def wheelEvent(self, evt: TTkMouseEvent) -> bool:
''' Handle mouse wheel events for scrolling
:param evt: the mouse event
:type evt: :py:class:`TTkMouseEvent`
def wheelEvent(self, evt:TTkMouseEvent) -> bool:
:return: True if the event was handled
:rtype: bool
'''
delta = TTkCfg.scrollDelta
offx, offy = self.getViewOffsets()
if evt.evt == TTkK.WHEEL_Up:
@ -216,20 +267,65 @@ class TTkAbstractScrollView(TTkContainer, TTkAbstractScrollViewInterface):
self.viewMoveTo(offx + delta, offy)
return True
def resizeEvent(self, w, h):
def resizeEvent(self, w: int, h: int) -> None:
''' Handle resize events
:param w: the new width
:type w: int
:param h: the new height
:type h: int
'''
self.viewMoveTo(self._viewOffsetX, self._viewOffsetY)
self.viewSizeChanged.emit(w,h)
self.viewChanged.emit()
def update(self, repaint=True, updateLayout=False, updateParent=False):
def update(self, repaint: bool = True, updateLayout: bool = False, updateParent: bool = False) -> None:
''' Update the widget and emit viewChanged signal if layout is updated
:param repaint: trigger a repaint, defaults to True
:type repaint: bool, optional
:param updateLayout: trigger a layout update, defaults to False
:type updateLayout: bool, optional
:param updateParent: trigger a parent update, defaults to False
:type updateParent: bool, optional
'''
if updateLayout:
self.viewChanged.emit()
return super().update(repaint, updateLayout, updateParent)
def setPadding(self, top, bottom, left, right) -> None:
def setPadding(self, top: int, bottom: int, left: int, right: int) -> None:
''' Set the padding and emit viewChanged signal
:param top: the top padding
:type top: int
:param bottom: the bottom padding
:type bottom: int
:param left: the left padding
:type left: int
:param right: the right padding
:type right: int
'''
super().setPadding(top, bottom, left, right)
self.viewChanged.emit()
def getViewOffsets(self) -> Tuple[int,int]:
'''
Retrieve the vertical and horizontal offsets of the :py:class:`TTkAbstractScrollViewInterface`
.. note::
Reimplement this function to handle this event
This method is already implemented in the following classes:
* :py:class:`TTkAbstractScrollView`
* :py:class:`TTkAbstractScrollViewLayout`
* :py:class:`TTkAbstractScrollViewGridLayout`
:return: the (x,y) offset
:rtype: tuple[int,int]
'''
return self._viewOffsetX, self._viewOffsetY
class TTkAbstractScrollViewLayout(TTkLayout, TTkAbstractScrollViewInterface):
'''
:py:class:`TTkAbstractScrollViewLayout`
@ -250,7 +346,7 @@ class TTkAbstractScrollViewLayout(TTkLayout, TTkAbstractScrollViewInterface):
:param width: the new width
:type width: int
:param height: the new heighht
:param height: the new height
:type height: int
'''
viewChanged:pyTTkSignal
@ -276,25 +372,68 @@ class TTkAbstractScrollViewLayout(TTkLayout, TTkAbstractScrollViewInterface):
self._excludeEvent = False
TTkLayout.__init__(self, *args, **kwargs)
def viewFullAreaSize(self) -> tuple[int,int]:
def viewFullAreaSize(self) -> Tuple[int,int]:
''' Return the full area size of the layout
:return: the (width, height) of the full area
:rtype: tuple[int,int]
'''
_,_,w,h = self.fullWidgetAreaGeometry()
return w,h
def viewDisplayedSize(self) -> tuple[int,int]:
def viewDisplayedSize(self) -> Tuple[int,int]:
''' Return the displayed size of the layout
:return: the (width, height) of the displayed area
:rtype: tuple[int,int]
'''
_,_,w,h = self.geometry()
return w,h
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
def viewMoveTo(self, x: int, y: int) -> None:
''' Move the view to the specified offset position
:param x: the horizontal offset
:type x: int
:param y: the vertical offset
:type y: int
'''
self.setOffset(-x,-y)
def getViewOffsets(self) -> tuple:
return self._viewOffsetX, self._viewOffsetY
def setGeometry(self, x: int, y: int, w: int, h: int) -> None:
''' Set the geometry and emit viewChanged signal
def setGeometry(self, x, y, w, h):
:param x: the horizontal position
:type x: int
:param y: the vertical position
:type y: int
:param w: the width
:type w: int
:param h: the height
:type h: int
'''
TTkLayout.setGeometry(self, x, y, w, h)
self.viewChanged.emit()
def getViewOffsets(self) -> Tuple[int,int]:
'''
Retrieve the vertical and horizontal offsets of the :py:class:`TTkAbstractScrollViewInterface`
.. note::
Reimplement this function to handle this event
This method is already implemented in the following classes:
* :py:class:`TTkAbstractScrollView`
* :py:class:`TTkAbstractScrollViewLayout`
* :py:class:`TTkAbstractScrollViewGridLayout`
:return: the (x,y) offset
:rtype: tuple[int,int]
'''
return self._viewOffsetX, self._viewOffsetY
class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterface):
'''
:py:class:`TTkAbstractScrollViewGridLayout`
@ -315,7 +454,7 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
:param width: the new width
:type width: int
:param height: the new heighht
:param height: the new height
:type height: int
'''
viewChanged:pyTTkSignal
@ -343,7 +482,14 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
TTkGridLayout.__init__(self, *args, **kwargs)
@pyTTkSlot(int, int)
def viewMoveTo(self, x: int, y: int):
def viewMoveTo(self, x: int, y: int) -> None:
''' Move the view to the specified offset position and propagate to child widgets
:param x: the horizontal offset
:type x: int
:param y: the vertical offset
:type y: int
'''
fw, fh = self.viewFullAreaSize()
dw, dh = self.viewDisplayedSize()
rangex = fw - dw
@ -353,7 +499,7 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
y = max(0,min(rangey,y))
# TTkLog.debug(f"x:{x},y:{y}, wo:{self._viewOffsetX,self._viewOffsetY}")
if self._viewOffsetX == x and \
self._viewOffsetY == y: # Nothong to do
self._viewOffsetY == y: # Nothing to do
return
self._excludeEvent = True
for widget in self.iterWidgets():
@ -365,24 +511,55 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
self.viewChanged.emit()
self.update()
def getViewOffsets(self) -> tuple:
return self._viewOffsetX, self._viewOffsetY
def setGeometry(self, x: int, y: int, w: int, h: int) -> None:
''' Set the geometry and emit viewChanged signal
def setGeometry(self, x, y, w, h):
:param x: the horizontal position
:type x: int
:param y: the vertical position
:type y: int
:param w: the width
:type w: int
:param h: the height
:type h: int
'''
TTkGridLayout.setGeometry(self, x, y, w, h)
self.viewChanged.emit()
@pyTTkSlot()
def _viewChanged(self):
def _viewChanged(self) -> None:
''' Internal slot to handle viewChanged signal from child widgets '''
if self._excludeEvent: return
self.viewChanged.emit()
@pyTTkSlot(int,int)
def _viewMovedTo(self, x, y):
def _viewMovedTo(self, x: int, y: int) -> None:
''' Internal slot to handle viewMovedTo signal from child widgets
:param x: the horizontal offset
:type x: int
:param y: the vertical offset
:type y: int
'''
if self._excludeEvent: return
self.viewMoveTo(x, y)
def addWidget(self, widget, row=None, col=None, rowspan=1, colspan=1):
''' Add a widget that implements :py:class:`TTkAbstractScrollViewInterface` to the grid layout
:param widget: the widget to be added (must implement TTkAbstractScrollViewInterface)
:type widget: :py:class:`TTkWidget`
:param row: the row position, optional, defaults to None
:type row: int, optional
:param col: the column position, optional, defaults to None
:type col: int, optional
:param rowspan: number of rows to span, defaults to 1
:type rowspan: int, optional
:param colspan: number of columns to span, defaults to 1
:type colspan: int, optional
:raises TypeError: if widget does not implement TTkAbstractScrollViewInterface
'''
if not issubclass(type(widget),TTkAbstractScrollViewInterface):
raise TypeError("TTkAbstractScrollViewInterface is required in TTkAbstractScrollViewGridLayout.addWidget(...)")
widget.viewChanged.connect(self._viewChanged)
@ -390,12 +567,32 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
return TTkGridLayout.addWidget(self, widget, row, col, rowspan, colspan)
def addItem(self, item, row=None, col=None, rowspan=1, colspan=1):
''' Add a layout item that implements :py:class:`TTkAbstractScrollViewInterface` to the grid layout
:param item: the layout item to be added (must implement TTkAbstractScrollViewInterface)
:type item: :py:class:`TTkLayoutItem`
:param row: the row position, optional, defaults to None
:type row: int, optional
:param col: the column position, optional, defaults to None
:type col: int, optional
:param rowspan: number of rows to span, defaults to 1
:type rowspan: int, optional
:param colspan: number of columns to span, defaults to 1
:type colspan: int, optional
:raises TypeError: if item does not implement TTkAbstractScrollViewInterface
'''
if not issubclass(type(item),TTkAbstractScrollViewInterface):
raise TypeError("TTkAbstractScrollViewInterface is required in TTkAbstractScrollViewGridLayout.addItem(...)")
return TTkGridLayout.addItem(self, item, row, col, rowspan, colspan)
# Override this function
def viewFullAreaSize(self) -> tuple[int,int]:
def viewFullAreaSize(self) -> Tuple[int,int]:
''' Return the full area size by computing the maximum size from all child widgets
:return: the (width, height) of the full area
:rtype: tuple[int,int]
'''
w,h=0,0
for widget in self.iterWidgets():
ww,wh = widget.viewFullAreaSize()
@ -404,7 +601,12 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
return w,h
# Override this function
def viewDisplayedSize(self) -> tuple[int,int]:
def viewDisplayedSize(self) -> Tuple[int,int]:
''' Return the displayed size by computing the maximum displayed size from all child widgets
:return: the (width, height) of the displayed area
:rtype: tuple[int,int]
'''
w,h=0,0
for widget in self.iterWidgets():
ww,wh = widget.viewDisplayedSize()
@ -412,3 +614,20 @@ class TTkAbstractScrollViewGridLayout(TTkGridLayout, TTkAbstractScrollViewInterf
h = max(h,wh)
return w,h
def getViewOffsets(self) -> Tuple[int,int]:
'''
Retrieve the vertical and horizontal offsets of the :py:class:`TTkAbstractScrollViewInterface`
.. note::
Reimplement this function to handle this event
This method is already implemented in the following classes:
* :py:class:`TTkAbstractScrollView`
* :py:class:`TTkAbstractScrollViewLayout`
* :py:class:`TTkAbstractScrollViewGridLayout`
:return: the (x,y) offset
:rtype: tuple[int,int]
'''
return self._viewOffsetX, self._viewOffsetY

13
libs/pyTermTk/TermTk/TTkAbstract/abstracttablemodel.py

@ -20,6 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import annotations
__all__ = ['TTkAbstractTableModel','TTkModelIndex']
from typing import Tuple,Any
@ -52,7 +54,7 @@ class TTkModelIndex():
:return: int
'''
pass
raise NotImplementedError()
def col(self) -> int:
'''
@ -60,7 +62,8 @@ class TTkModelIndex():
:return: int
'''
pass
raise NotImplementedError()
def data(self) -> object:
'''
@ -68,7 +71,7 @@ class TTkModelIndex():
:return: object
'''
pass
raise NotImplementedError()
def setData(self, data:object) -> None:
'''
@ -77,11 +80,11 @@ class TTkModelIndex():
:param data: the data to be set in the (row,col) position of the table
:type data: object
'''
pass
raise NotImplementedError()
class _TTkModelIndexList(TTkModelIndex):
__slots__ = ('_col','_row','_model')
def __init__(self, row:int, col:list, model) -> None:
def __init__(self, row:int, col:int, model:TTkAbstractTableModel) -> None:
self._col = col
self._row = row
self._model = model

4
libs/pyTermTk/TermTk/TTkCore/constant.py

@ -169,7 +169,7 @@ class TTkConstant:
HORIZONTAL = Direction.HORIZONTAL
VERTICAL = Direction.VERTICAL
class ScrollBarPolicy(int):
class ScrollBarPolicy(IntEnum):
ScrollBarAsNeeded = 0x00
ScrollBarAlwaysOff = 0x01
ScrollBarAlwaysOn = 0x02
@ -543,7 +543,7 @@ class TTkConstant:
ClearAndSelect = Clear | Select
'''A combination of Clear and Select, provided for convenience.'''
class ItemFlag(int):
class ItemFlag(Flag):
''':py:class:`ItemFlag` describes the properties of an item
.. autosummary::

6
libs/pyTermTk/TermTk/TTkTestWidgets/tominspector.py

@ -22,6 +22,8 @@
__all__ = ['TTkTomInspector']
from typing import List
from TermTk.TTkCore.cfg import TTkCfg
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.helper import TTkHelper
@ -75,6 +77,7 @@ class _DetailGridView(TTkAbstractScrollView):
class _DetailLazyFormView(TTkAbstractScrollView):
__slots__ = ('_gridLayout', '_lazyRows', '_lastRow')
_lazyRows:List[List]
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.setPadding(1,0,0,0)
@ -149,7 +152,8 @@ class TTkTomInspector(TTkContainer):
self._domTree = TTkTree()
self._domTree.setHeaderLabels(["Object", "Class", "Visibility", "Layout"])
self._domTree.addTopLevelItem(TTkTomInspector._getTomTreeItem(TTkHelper._rootWidget._widgetItem))
if TTkHelper._rootWidget:
self._domTree.addTopLevelItem(TTkTomInspector._getTomTreeItem(TTkHelper._rootWidget._widgetItem))
self._detail = TTkFrame()

2
libs/pyTermTk/TermTk/TTkWidgets/TTkModelView/tree.py

@ -25,7 +25,7 @@ __all__ = ['TTkTree']
from typing import List,Optional
from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.string import TTkString, TTkStringType
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot
from TermTk.TTkWidgets.TTkModelView.treewidget import TTkTreeWidget
from TermTk.TTkWidgets.TTkModelView.treewidgetitem import TTkTreeWidgetItem

26
libs/pyTermTk/TermTk/TTkWidgets/TTkTerminal/debugterminal.py

@ -20,7 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
__all__ = ['DebugTTkTerminal']
# __all__ = ['DebugTTkTerminal']
__all__ = []
import os, pty, threading
import struct, fcntl, termios
@ -48,6 +49,7 @@ from TermTk.TTkAbstract.abstractscrollarea import TTkAbstractScrollArea
from TermTk.TTkAbstract.abstractscrollview import TTkAbstractScrollView, TTkAbstractScrollViewGridLayout
from TermTk.TTkWidgets.widget import TTkWidget
from TermTk.TTkWidgets.TTkTerminal import TTkTerminal
from TermTk.TTkWidgets.TTkTerminal.mode import TTkTerminalModes
from TermTk.TTkWidgets.TTkTerminal.vt102 import TTkVT102
@ -55,14 +57,16 @@ from TermTk.TTkWidgets.TTkTerminal.vt102 import TTkVT102
from TermTk.TTkCore.TTkTerm.colors import TTkTermColor
from TermTk.TTkCore.TTkTerm.colors_ansi_map import ansiMap16, ansiMap256
class DebugTTkTerminal(TTkWidget):
__slots__ = ('_terminal')
def __init__(self, terminal, **kwargs) -> None:
super().__init__(**kwargs)
# class DebugTTkTerminal(TTkWidget):
# __slots__ = ('_terminal')
# _terminal:TTkTerminal
# def __init__(self, terminal, **kwargs) -> None:
# self._terminal = terminal
# super().__init__(**kwargs)
def paintEvent(self, canvas: TTkCanvas):
t = self._terminal
canvas.drawText(pos=(0,0), text=f"{t=}")
canvas.drawText(pos=(0,1), text=f"{t._terminalCursor=}")
canvas.drawText(pos=(0,2), text=f"{t._scrollingRegion=}")
canvas.drawText(pos=(0,3), text=f"{len(t._bufferedLines)=}")
# def paintEvent(self, canvas: TTkCanvas):
# t = self._terminal
# canvas.drawText(pos=(0,0), text=f"{t=}")
# canvas.drawText(pos=(0,1), text=f"{t._terminalCursor=}")
# canvas.drawText(pos=(0,2), text=f"{t._scrollingRegion=}")
# canvas.drawText(pos=(0,3), text=f"{len(t._bufferedLines)=}")

2
tests/pytest/modelView/test_tablemodelcsv.py

@ -306,7 +306,7 @@ class TestTTkTableModelCSV:
model = ttk.TTkTableModelCSV(fd=csv_fd)
# Test inherited methods
assert isinstance(model.flags(0, 0), int)
assert isinstance(model.flags(0, 0), ttk.TTkK.ItemFlag)
# Test setData (inherited)
original_value = model.data(0, 0)

2
tests/pytest/modelView/test_tablemodellist.py

@ -514,7 +514,7 @@ def test_integration_with_table_widget():
assert isinstance(model.rowCount(), int)
assert isinstance(model.columnCount(), int)
assert isinstance(model.data(0, 0), (str, int, float, type(None)))
assert isinstance(model.flags(0, 0), int) # Flags are integer bitmasks
assert isinstance(model.flags(0, 0), ttk.TTkK.ItemFlag) # Flags are integer bitmasks
if __name__ == '__main__':

Loading…
Cancel
Save