rename class TUI to App, change StdOutWrapper to a context manager and add idea of a main_loop() for the App class

This commit is contained in:
2020-01-14 08:59:13 +01:00
parent 033cb92dc4
commit d0eabd3252
7 changed files with 186 additions and 145 deletions

View File

@@ -37,7 +37,7 @@
<span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;TUI module.</span>
<span class="sd">:Date: 2020-01-10</span>
<span class="sd">:Date: 2020-01-13</span>
<span class="sd">.. module:: tui</span>
<span class="sd"> :platform: *nix, Windows</span>
@@ -62,43 +62,58 @@
<div class="viewcode-block" id="StdOutWrapper"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.StdOutWrapper">[docs]</a><span class="k">class</span> <span class="nc">StdOutWrapper</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Send print to stdout (print to the standard console).</span>
<span class="sd"> usage:</span>
<span class="sd"> :Example:</span>
<span class="sd"> ::</span>
<span class="sd"> # catch all prints into StdOutWrapper</span>
<span class="sd"> mystdout = StdOutWrapper()</span>
<span class="sd"> sys.stdout = mystdout</span>
<span class="sd"> sys.stderr = mystdout</span>
<span class="sd"> with StdOutWrapper() as mystdout:</span>
<span class="sd"> # begin curses (curses.initscr())</span>
<span class="sd"> # begin curses (curses.initscr(), ...)</span>
<span class="sd"> # do your stuff here</span>
<span class="sd"> # print(&quot;foo&quot;)</span>
<span class="sd"> # you can also output mystdout.get_text() in a ncurses widget in</span>
<span class="sd"> # runtime</span>
<span class="sd"> # do your stuff here</span>
<span class="sd"> # print(&quot;foo&quot;)</span>
<span class="sd"> # you can also output mystdout.get_text() in a ncurses widget in</span>
<span class="sd"> # runtime</span>
<span class="sd"> # end curses (curses.endwin())</span>
<span class="sd"> # end curses (curses.endwin())</span>
<span class="sd"> # go back to normal state and print all catched prints to stdout</span>
<span class="sd"> sys.stdout = sys.__stdout__</span>
<span class="sd"> sys.stderr = sys.__stderr__</span>
<span class="sd"> sys.stdout.write(mystdout.get_text())</span>
<span class="sd"> source:</span>
<span class="sd"> https://stackoverflow.com/a/14010948</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># https://stackoverflow.com/a/14010948</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;catch all prints into StdOutWrapper</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1">#self.stdout = StdOutWrapper()</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="bp">self</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="bp">self</span>
<span class="k">return</span> <span class="bp">self</span> <span class="c1"># to use as: with StdOutWrapper() as mystdout:</span>
<span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">etype</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;go back to normal state and print all catched prints to</span>
<span class="sd"> stdout</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">__stdout__</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">__stderr__</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_text</span><span class="p">())</span>
<div class="viewcode-block" id="StdOutWrapper.write"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.StdOutWrapper.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">txt</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;print uses write()</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">+=</span> <span class="n">txt</span>
<span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)[</span><span class="o">-</span><span class="mi">30</span><span class="p">:])</span></div>
<div class="viewcode-block" id="StdOutWrapper.get_text"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.StdOutWrapper.get_text">[docs]</a> <span class="k">def</span> <span class="nf">get_text</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">))</span></div></div>
<span class="c1">#def get_text(self,beg,end):</span>
<span class="c1"># return &#39;\n&#39;.join(self.text.split(&#39;\n&#39;)[beg:end])</span>
<div class="viewcode-block" id="TUI"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI">[docs]</a><span class="k">class</span> <span class="nc">TUI</span><span class="p">:</span>
<div class="viewcode-block" id="App"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App">[docs]</a><span class="k">class</span> <span class="nc">App</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;TUI text-based user interface</span>
<span class="sd"> initscr is the encapsulation window object of the stdscr</span>
@@ -114,14 +129,9 @@
<span class="k">try</span><span class="p">:</span>
<span class="n">delay</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">delay</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;TUI(delay)&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;App(delay)&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Could not convert the argument to an integer.&quot;</span><span class="p">)</span>
<span class="c1"># catch all prints into StdOutWrapper</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">StdOutWrapper</span><span class="p">()</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stdout</span>
<span class="c1"># Define the appearance of some interface elements</span>
<span class="n">hotkey_attr</span> <span class="o">=</span> <span class="n">curses</span><span class="o">.</span><span class="n">A_BOLD</span> <span class="o">|</span> <span class="n">curses</span><span class="o">.</span><span class="n">A_UNDERLINE</span>
<span class="n">menu_attr</span> <span class="o">=</span> <span class="n">curses</span><span class="o">.</span><span class="n">A_NORMAL</span>
@@ -153,10 +163,28 @@
<span class="bp">self</span><span class="o">.</span><span class="n">last_pressed_ch</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># getch() Note that the integer returned does not have to be in ASCII range: function keys, keypad keys and so on return numbers higher than 256.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">last_pressed_mouse_ch</span> <span class="o">=</span> <span class="mi">0</span>
<div class="viewcode-block" id="TUI.refresh"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.refresh">[docs]</a> <span class="k">def</span> <span class="nf">refresh</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="App.main_loop"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.main_loop">[docs]</a> <span class="k">def</span> <span class="nf">main_loop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">StdOutWrapper</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;kkkk&#39;</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;kkkk&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_pressed_ch</span> <span class="o">==</span> <span class="nb">ord</span><span class="p">(</span><span class="s1">&#39;q&#39;</span><span class="p">):</span>
<span class="k">break</span>
<span class="bp">self</span><span class="o">.</span><span class="n">refresh</span><span class="p">()</span> <span class="c1"># update the screen</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;kkkk&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">getch</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">end</span><span class="p">()</span></div>
<div class="viewcode-block" id="App.refresh"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.refresh">[docs]</a> <span class="k">def</span> <span class="nf">refresh</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">initscr</span><span class="o">.</span><span class="n">refresh</span><span class="p">()</span> <span class="c1"># update the screen</span></div>
<div class="viewcode-block" id="TUI.getch"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.getch">[docs]</a> <span class="k">def</span> <span class="nf">getch</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="App.getch"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.getch">[docs]</a> <span class="k">def</span> <span class="nf">getch</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># keep last key value</span>
<span class="n">last_pressed_ch_current</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initscr</span><span class="o">.</span><span class="n">getch</span><span class="p">()</span>
<span class="k">if</span> <span class="n">last_pressed_ch_current</span> <span class="o">!=</span> <span class="n">curses</span><span class="o">.</span><span class="n">ERR</span><span class="p">:</span>
@@ -168,7 +196,7 @@
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">last_pressed_ch</span> <span class="o">=</span> <span class="n">last_pressed_ch_current</span></div>
<div class="viewcode-block" id="TUI.color_table"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.color_table">[docs]</a> <span class="k">def</span> <span class="nf">color_table</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="App.color_table"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.color_table">[docs]</a> <span class="k">def</span> <span class="nf">color_table</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">window</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Print all available colors with default background.</span>
<span class="sd"> Check if curses.has_colors() is True.</span>
<span class="sd"> &quot;&quot;&quot;</span>
@@ -198,7 +226,7 @@
<span class="c1"># End of screen reached</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="TUI.color_def"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.color_def">[docs]</a> <span class="k">def</span> <span class="nf">color_def</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="App.color_def"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.color_def">[docs]</a> <span class="k">def</span> <span class="nf">color_def</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="n">curses</span><span class="o">.</span><span class="n">can_change_color</span><span class="p">():</span> <span class="c1"># if True curses.init_color(color_number, r, g, b) can be used</span>
<span class="k">pass</span></div>
<span class="c1"># changes colors for the terminal also after closing the program.</span>
@@ -211,21 +239,16 @@
<span class="c1">#curses.init_color(1, *tmp)</span>
<span class="c1">#print(curses.color_content(1))</span>
<div class="viewcode-block" id="TUI.clear"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="App.clear"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stdscr</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span></div>
<div class="viewcode-block" id="TUI.end"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.TUI.end">[docs]</a> <span class="k">def</span> <span class="nf">end</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<div class="viewcode-block" id="App.end"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.App.end">[docs]</a> <span class="k">def</span> <span class="nf">end</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;clean up&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stdscr</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="n">curses</span><span class="o">.</span><span class="n">nocbreak</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stdscr</span><span class="o">.</span><span class="n">keypad</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">curses</span><span class="o">.</span><span class="n">echo</span><span class="p">()</span>
<span class="n">curses</span><span class="o">.</span><span class="n">endwin</span><span class="p">()</span>
<span class="c1"># go back to normal state and print all catched prints to stdout</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">__stdout__</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stderr</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">__stderr__</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">get_text</span><span class="p">())</span></div></div>
<span class="n">curses</span><span class="o">.</span><span class="n">endwin</span><span class="p">()</span></div></div>
<div class="viewcode-block" id="Window"><a class="viewcode-back" href="../../pylib.tui.html#pylib.tui.Window">[docs]</a><span class="k">class</span> <span class="nc">Window</span><span class="p">:</span>