diff --git a/TermTk/TTkCore/signal.py b/TermTk/TTkCore/signal.py index bac8b84e..67fef876 100644 --- a/TermTk/TTkCore/signal.py +++ b/TermTk/TTkCore/signal.py @@ -24,7 +24,7 @@ # https://github.com/ceccopierangiolieugenio/pyCuT/blob/master/cupy/CuTCore/CuSignal.py ''' -Signals & Slots [`Tutorial `__] +Signals & Slots [:ref:`Tutorial `] ========================================================================================================================= Signals and slots are used for communication between objects. diff --git a/TermTk/TTkLayouts/boxlayout.py b/TermTk/TTkLayouts/boxlayout.py index 2646b1c0..84513791 100644 --- a/TermTk/TTkLayouts/boxlayout.py +++ b/TermTk/TTkLayouts/boxlayout.py @@ -21,7 +21,7 @@ # SOFTWARE. ''' -**Box Layout** [`Tutorial `__] +**Box Layout** [:ref:`Tutorial `] ''' __all__ = ['TTkHBoxLayout', 'TTkVBoxLayout'] diff --git a/TermTk/TTkLayouts/gridlayout.py b/TermTk/TTkLayouts/gridlayout.py index 043b73fc..31589cba 100644 --- a/TermTk/TTkLayouts/gridlayout.py +++ b/TermTk/TTkLayouts/gridlayout.py @@ -21,7 +21,7 @@ # SOFTWARE. ''' -**Grid Layout** [`Tutorial `__] +**Grid Layout** [:ref:`Tutorial `] ''' __all__ = ['TTkGridLayout'] diff --git a/TermTk/TTkLayouts/layout.py b/TermTk/TTkLayouts/layout.py index ca9736ac..7f772fb7 100644 --- a/TermTk/TTkLayouts/layout.py +++ b/TermTk/TTkLayouts/layout.py @@ -21,7 +21,7 @@ # SOFTWARE. ''' -**Layout** [`Tutorial `__] +**Layout** [:ref:`Tutorial `] ''' __all__ = ['TTkLayoutItem', 'TTkLayout'] diff --git a/TermTk/TTkWidgets/TTkPickers/filepicker.py b/TermTk/TTkWidgets/TTkPickers/filepicker.py index a13e17f7..638089b6 100644 --- a/TermTk/TTkWidgets/TTkPickers/filepicker.py +++ b/TermTk/TTkWidgets/TTkPickers/filepicker.py @@ -377,7 +377,8 @@ class TTkFileDialog: pass class TTkFileButtonPicker(TTkButton): - ''' TTkFileButtonPicker: + ''' + TTkFileButtonPicker: :: @@ -410,11 +411,9 @@ class TTkFileButtonPicker(TTkButton): ║Files of type:[All Files (*) ^][Cancel]║ ╚═════════════════════════════════════════════════════════════════════════╝ - Demo: `formwidgets.py `_ + Demo: `filepicker.py `_ (`Try Online `__) - `ttkdesigner Tutorial `_ - :param path: the current path used in the file dialog, defaults to "." :type path: str, optional @@ -438,31 +437,32 @@ class TTkFileButtonPicker(TTkButton): :param acceptMode: TThe action mode defines whether the dialog is for opening or saving files, defaults to :py:class:`~TermTk.TTkCore.constant.TTkConstant.AcceptMode.AcceptOpen` :type acceptMode: :py:class:`TTkConstant.AcceptMode`, optional - +-----------------------------------------------------------------------------------------------+ - | `Signals `_ | - +-----------------------------------------------------------------------------------------------+ - - .. py:method:: pathPicked(pathName:pyTTkSignal - - This signal is emitted whenever any path is picked (Files/Dir) - - :param pathName: the name of the path - :type pathName: str + ''' - .. py:method:: filePicked(fileName:pyTTkSignal + pathPicked:pyTTkSignal + ''' + This signal is emitted whenever any path is picked (Files/Dir) - This signal is emitted whenever any file is picked + :param pathName: the name of the path + :type pathName: str + ''' - :param fileName: the name of the file - :type fileName: str + filePicked:pyTTkSignal + ''' + This signal is emitted whenever any file is picked - .. py:method:: folderPicked(dirName:pyTTkSignal + :param fileName: the name of the file + :type fileName: str + ''' - This signal is emitted whenever any folder is picked + folderPicked:pyTTkSignal + ''' + This signal is emitted whenever any folder is picked - :param dirName: the name of the folder - :type dirName: str + :param dirName: the name of the folder + :type dirName: str ''' + __slots__ = ('_filter', '_caption', '_fileMode', '_acceptMode', '_path' # Signals 'pathPicked', 'filePicked', 'filesPicked', 'folderPicked') diff --git a/TermTk/TTkWidgets/TTkTerminal/terminalhelper.py b/TermTk/TTkWidgets/TTkTerminal/terminalhelper.py index ae3102aa..a15823ef 100644 --- a/TermTk/TTkWidgets/TTkTerminal/terminalhelper.py +++ b/TermTk/TTkWidgets/TTkTerminal/terminalhelper.py @@ -29,13 +29,57 @@ from select import select from TermTk.TTkCore.signal import pyTTkSignal,pyTTkSlot from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.helper import TTkHelper +from TermTk.TTkWidgets.TTkTerminal.terminal import TTkTerminal class TTkTerminalHelper(): + ''' + :py:class:`TTkTerminalHelper` is a convenience class that simplify the initilization and the handling of a `pty `__ terminal session + + .. note:: + This helper is available only on Linux and Mac + + Quickstart: + + .. code-block:: python + + import TermTk as ttk + + root = ttk.TTk(mouseTrack=True) + + win = ttk.TTkWindow(parent=root, title="Terminal", size=(80+2,24+4), layout=ttk.TTkGridLayout()) + + term = ttk.TTkTerminal(parent=win) + + th = ttk.TTkTerminalHelper(term=term) + th.runShell() + + root.mainloop() + + ''' + + dataOut:pyTTkSignal + ''' + This signal is emitted when some data is available in the pty interface + + :param data: the pty data + :type data: str + ''' + + terminalClosed:pyTTkSignal + ''' + This signal is emitted when the pty session ends + ''' + __slots__ = ('_shell', '_fd', '_inout', '_pid', '_quit_pipe', '_size', '_term', #Signals 'terminalClosed', 'dataOut') - def __init__(self, term=None) -> None: + def __init__(self, *, + term:TTkTerminal=None) -> None: + ''' + :param term: The terminal handled by this helper. + :type term: :py:class:`TTkTerminal` + ''' self.dataOut = pyTTkSignal(str) self.terminalClosed = pyTTkSignal() self._shell = [os.environ.get('SHELL', 'sh')] @@ -49,14 +93,27 @@ class TTkTerminalHelper(): if term: self.attachTTkTerminal(term) - def attachTTkTerminal(self, term): + def attachTTkTerminal(self, term:TTkTerminal) -> None: + ''' + Attach a :py:class:`TTkTerminal` to this helper. + + :param term: The terminal handled by this helper. + :type term: :py:class:`TTkTerminal` + ''' + self._term = term self.dataOut.connect(term.termWrite) term.termData.connect(self.push) term.termResized.connect(self.resize) term.closed.connect(self._quit) - def runShell(self, program=None): + def runShell(self, program:str=None) -> None: + ''' + Run a "program" attaching it the the pty session linked to this terminal. + + :param program: The program required to run, defaults to the cmd defined bu the "SHELL" env variable or "sh" if missing + :type program: str, optional + ''' self._shell = program if program else self._shell if isinstance(self._shell, str): self._shell = [self._shell] @@ -88,19 +145,33 @@ class TTkTerminalHelper(): self._term = None @pyTTkSlot(int, int) - def resize(self, w: int, h: int): + def resize(self, width: int, height: int) -> None: + ''' + Send a resize "`TIOCSWINSZ `__" ioctl to the pty session + + :param width: the new width + :type width: int + :param height: the new height + :type height: int + ''' # if w<=0 or h<=0: return # if self._fd: # s = struct.pack('HHHH', h, w, 0, 0) # t = fcntl.ioctl(self._fd, termios.TIOCSWINSZ, s) - if self._fd and self._size != (w,h): - self._size = (w,h) - if w<=0 or h<=0: return - s = struct.pack('HHHH', h, w, 0, 0) + if self._fd and self._size != (width,height): + self._size = (width,height) + if width<=0 or height<=0: return + s = struct.pack('HHHH', height, width, 0, 0) t = fcntl.ioctl(self._fd, termios.TIOCSWINSZ, s) @pyTTkSlot(str) - def push(self, data:str): + def push(self, data:str) -> None: + ''' + Send the data to the pty session + + :param data: the data + :type data: str + ''' self._inout.write(data) @pyTTkSlot() @@ -118,7 +189,22 @@ class TTkTerminalHelper(): except: pass - def loop(self): + def loop(self) -> None: + ''' + This is the main loop routine responsible of handling the pty and terminal events, + for example, forwarding the input codes to the pty session and the pty output to the terminal emulator. + + :: + + TTkTerminal + ╔═══════╗ pty + ║ C:\ ║ --[ KeyPresses, MouseEvents, ResizeSignal, ... ]--> ┌────┈┄╶ + ║ ║ <---------[ Output, Ansi escape codes, ... ]------- │ bash, sh, ... + ╚═══════╝ └────┈┄╶ + + .. caution:: Do not touch this! (unless you know what you are doing) + ''' + while rs := select( [self._inout,self._quit_pipe[0]], [], [])[0]: if self._quit_pipe[0] in rs: # os.close(self._quit_pipe[0]) diff --git a/TermTk/TTkWidgets/TTkTerminal/terminalview.py b/TermTk/TTkWidgets/TTkTerminal/terminalview.py index 834e01c8..4eec8983 100644 --- a/TermTk/TTkWidgets/TTkTerminal/terminalview.py +++ b/TermTk/TTkWidgets/TTkTerminal/terminalview.py @@ -62,7 +62,6 @@ class _termLog(): class TTkTerminalView(TTkAbstractScrollView, _TTkTerminal_CSI_DEC): ''' - :py:class:`TTkTerminalView` is a terminal emulator fot TermTk .. warning:: @@ -145,7 +144,7 @@ class TTkTerminalView(TTkAbstractScrollView, _TTkTerminal_CSI_DEC): terminalClosed:pyTTkSignal ''' - This signal is emitted when the terminl is closed. + This signal is emitted when the terminal is closed. ''' titleChanged:pyTTkSignal diff --git a/TermTk/TTkWidgets/texedit.py b/TermTk/TTkWidgets/texedit.py index 2131a057..4ba1073f 100644 --- a/TermTk/TTkWidgets/texedit.py +++ b/TermTk/TTkWidgets/texedit.py @@ -121,8 +121,7 @@ class TTkTextEditView(TTkAbstractScrollView): Demo: `textedit.py `_ (`Try Online `__) - `ttkdesigner Tutorial `_ - + :ref:`ttkdesigner Tutorial ` ''' currentColorChanged:pyTTkSignal diff --git a/tests/t.pty/test.pty.006.terminal.06.py b/tests/t.pty/test.pty.006.terminal.06.py index 17f9028e..91f0d152 100755 --- a/tests/t.pty/test.pty.006.terminal.06.py +++ b/tests/t.pty/test.pty.006.terminal.06.py @@ -61,7 +61,7 @@ te = ttk.TTkTextEdit(parent=winT, readOnly=False, lineNumber=True) clipboard = ttk.TTkClipboard() -@ttk.pyTTkSlot(str) +@ttk.pyTTkSlot(ttk.TTkString) def _textSelected(text, te=te): te.setText("Selected Text in the terminal:") te.append( "------------------------------\n") diff --git a/tests/t.pty/test.pty.006.terminal.07.py b/tests/t.pty/test.pty.006.terminal.07.py index 3b252b38..4357186f 100755 --- a/tests/t.pty/test.pty.006.terminal.07.py +++ b/tests/t.pty/test.pty.006.terminal.07.py @@ -61,7 +61,7 @@ te = ttk.TTkTextEdit(parent=winT, readOnly=False, lineNumber=True) clipboard = ttk.TTkClipboard() -@ttk.pyTTkSlot(str) +@ttk.pyTTkSlot(ttk.TTkString) def _textSelected(text, te=te): te.setText("Selected Text in the terminal:") te.append( "------------------------------\n") diff --git a/tutorial/003-signalslots.rst b/tutorial/003-signalslots.rst index 0363de62..452399dd 100644 --- a/tutorial/003-signalslots.rst +++ b/tutorial/003-signalslots.rst @@ -47,7 +47,13 @@ Signal and Slots | A slot is a function that is called in response to a particular signal. | TermTk_'s TTkWidgets_ have many predefined signals/slots, but it is possible to subclass any TTkWidgets_ and add our own signals/slots to them. -.. image:: https://ceccopierangiolieugenio.github.io/pyTermTk/_images/Signal.Slots.001.svg +.. image:: ../_images/Signal.Slots.001.svg + +.. #Methods +.. #======= +.. # +.. #.. autofunction:: TermTk.pyTTkSignal +.. #.. autodecorator:: TermTk.pyTTkSlot Examples ======== diff --git a/tutorial/ttkDesigner/textEdit/README.rst b/tutorial/ttkDesigner/textEdit/README.rst index 0484acee..67d405bb 100644 --- a/tutorial/ttkDesigner/textEdit/README.rst +++ b/tutorial/ttkDesigner/textEdit/README.rst @@ -21,6 +21,9 @@ .. contents:: +.. _TextEdit_ttkDesigner-Tutorial_Intro: + + =================== ttkDesigner_ - Your first TextEditor ===================