title: Text Display in Tkinter 01 tags: python tk ## Usage ```bash tkt file.txt # display file.txt tkt f1 f2 f3 # display f1, f2, f3 concatenated tkt - # take text from stdin tkt # same as tkt - tkt -c # display clipboard contents (gets via pp) ``` ## The Code There is a pretty random feature I added for my own purposes: you can pass arguments of the form `x=my command arg1 arg2` and instead of seeing this as a file, it sees it as a keybinding, so pressing `x` will `execv('/bin/env',['env','my','command','arg1','arg2'])`. Note that you can't do anything like quoting in the command passed in here (generally I avoid the need to quote when giving files names). Note that the command will simply quit if `env` fails to execute the command (this program has no idea whether the command will succeed, and makes no attempt to find out -- a more robust version may use e.g. `shutil.which` to see if the command exists, and use the result instead of being lazy and throwing the ball to `env`). ```py #!/usr/bin/env python from icecream import ic; ic.configureOutput(includeContext=True) import re import os import tkinter as tk import tkinter.font as tkfont import sys from subprocess import run stdin = None txts = [] args = sys.argv[1:] if len(args) == 0: args = ["-"] kmap = {} for arg in args: if arg == "-": if stdin is None: stdin = sys.stdin.read() txts.append(stdin) elif "=" in arg: a,b = arg.split("=",1) bs = re.split(r"\s+",b.strip()) kmap[a] = bs elif arg == "-c": txts.append(run("pp",capture_output=True).stdout.decode()) else: with open(arg) as f: txts.append(f.read()) txt = "\n".join(txts) def key_handler(event): print(event.char, event.keysym, event.keycode) ic(event) if event.char == "q": exit() match event.char: case "q": exit() case "\x03": sel = T.selection_get() root.clipboard_clear() root.clipboard_append(sel) print("Copied:",sel) return match event.keysym: case "Down": return T.yview(tk.SCROLL,1,tk.UNITS) case "Up": return T.yview(tk.SCROLL,-1,tk.UNITS) case "Prior": return T.yview(tk.SCROLL,-1,tk.PAGES) case "Next": return T.yview(tk.SCROLL,1,tk.PAGES) if event.char in kmap: cmd = kmap[event.char] os.execv("/bin/env",["env"]+cmd) root = tk.Tk() root.bind("", key_handler) # get screen size screen_width = root.winfo_screenwidth() screen_height = root.winfo_screenheight() win_width = int(screen_width * 0.7) win_height = int(screen_height * 0.7) win_xoffs = int((screen_width-win_width)/2) win_yoffs = int((screen_height-win_height)/2) geom = f"{win_width}x{win_height}+{win_xoffs}+{win_yoffs}" desired_font = tkfont.Font(family="Hack Nerd Font Mono", size=14) root.geometry(geom) S = tk.Scrollbar(root) T = tk.Text(root, height=4, width=50) T.configure(font = desired_font,bg="#002",fg="#ffc") S.pack(side=tk.RIGHT, fill=tk.Y) T.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) S.config(command=T.yview) T.config(yscrollcommand=S.set) T.insert(tk.END, txt) T.configure(state=tk.DISABLED) tk.mainloop() ```