Skip to content

Commit

Permalink
add tk.TextWindow
Browse files Browse the repository at this point in the history
  • Loading branch information
lidong committed Jun 29, 2024
1 parent 968c269 commit a9a78fc
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
### 0.1.0 (2024-06-29)
1. add `tk.TextWindow`
2.

### 0.0.9 (2024-06-26)
1. add `tk.TKit.ask_text`
2. focus_force for `tk.TKit`
Expand Down
2 changes: 1 addition & 1 deletion morebuiltins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.0.9"
__version__ = "0.1.0"
__all__ = [
"morebuiltins.utils",
"morebuiltins.date",
Expand Down
112 changes: 112 additions & 0 deletions morebuiltins/tk.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import builtins
import tkinter as tk
import tkinter.messagebox
from threading import Thread
from tkinter import scrolledtext
from typing import Any, Dict

__all__ = ["TKit"]
Expand Down Expand Up @@ -46,6 +49,7 @@ def resize_tk(
fullscreen=False,
toolwindow=False,
disabled=False,
title=None,
):
"""Resize and Move the window to the given position, default to the center of the screen."""
screen_width = tk_obj.winfo_screenwidth()
Expand All @@ -62,6 +66,8 @@ def resize_tk(
tk_obj.attributes("-fullscreen", fullscreen)
tk_obj.attributes("-toolwindow", toolwindow)
tk_obj.attributes("-disabled", disabled)
if title is not None:
tk_obj.title(title)

@classmethod
def ask(cls, arg: Any, message="", title="", **kwargs):
Expand All @@ -78,6 +84,18 @@ def ask(cls, arg: Any, message="", title="", **kwargs):
else:
raise TypeError()

@classmethod
def info(cls, message="", title="", **kwargs):
return cls.ask_msgbox(0, message, title, **kwargs)

@classmethod
def warn(cls, message="", title="", **kwargs):
return cls.ask_msgbox(1, message, title, **kwargs)

@classmethod
def error(cls, message="", title="", **kwargs):
return cls.ask_msgbox(2, message, title, **kwargs)

@classmethod
def ask_msgbox(cls, arg: int, message="", title="", **kwargs):
methods = (
Expand Down Expand Up @@ -229,6 +247,76 @@ def submit(event=None):
root.mainloop()
return text_var.get()

@classmethod
def text_context(cls, function, *args, **kwargs):
return TextWindow(function, *args, **kwargs)


class TextWindow:
def __init__(self, function, *args, **kwargs):
self.print = print
self.function = function
self.args = args
self.kwargs = kwargs

self.result = None
self.error = None
self._shutdown = False

def print_text(self, *args, end="\n", sep=" ", file=None, flush=False):
if flush:
self.text_box.delete("1.0", tk.END)
self.text_box.insert(tk.END, f"{sep.join(map(str, args))}{end}")
self.text_box.see(tk.END)

def patch_print(self):
builtins.print = self.print_text

def restore_print(self):
if builtins.print is not self.print:
builtins.print = self.print

def run(self):
try:
self.result = self.function(*self.args, **self.kwargs)
except Exception as e:
self.error = e
finally:
self.shutdown()

def __enter__(self):
try:
self.root = tk.Tk()
__resize_kwargs = self.kwargs.pop("__resize_kwargs", {})
TKit.resize_tk(self.root, **__resize_kwargs)
__text_kwargs = self.kwargs.pop("__text_kwargs", {})
self.text_box = scrolledtext.ScrolledText(self.root, **__text_kwargs)
self.text_box.pack(expand=True, fill="both")
self.text_box.focus_force()
self.patch_print()
t = Thread(target=self.run, daemon=True)
t.start()
self.root.mainloop()
finally:
self.shutdown()
if self.error:
raise self.error

return self.result

def shutdown(self):
try:
if not self._shutdown:
self._shutdown = True
self.restore_print()
self.root.quit()
except (tk.TclError, AttributeError):
pass

def __exit__(self, *_):
self.root.withdraw()
self.shutdown()


def examples():
while True:
Expand Down Expand Up @@ -259,6 +347,30 @@ def examples():
if result != "1\n":
TKit.ask(2, "Wrong text %s" % repr(result))
continue

def test_text(flush=False):
import time

for i in range(50):
print(f"Test print flush={flush} -- {i}", flush=flush)
time.sleep(0.02)
return "OK"

with TKit.text_context(
test_text,
flush=True,
__resize_kwargs={"title": "The Title", "toolwindow": True},
__text_kwargs={"font": "_ 15"},
) as result:
TKit.info("result=%s" % result)

with TKit.text_context(
test_text,
flush=False,
__resize_kwargs={"title": "The Title", "toolwindow": True},
__text_kwargs={"font": "_ 15"},
) as result:
TKit.warn("result=%s" % result)
break


Expand Down

0 comments on commit a9a78fc

Please sign in to comment.