tk version of zenitY
This commit is contained in:
1
bin/tk-zenity
Symbolic link
1
bin/tk-zenity
Symbolic link
@@ -0,0 +1 @@
|
||||
../shell/tk-zenity
|
||||
175
shell/tk-zenity
Executable file
175
shell/tk-zenity
Executable file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
import tkinter as tk
|
||||
import tkinter.messagebox
|
||||
import tkinter.simpledialog
|
||||
import tkinter.ttk
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class StdinBox(tk.Toplevel):
|
||||
def __init__(self, title="", message="", geometry="800x80"):
|
||||
tk.Toplevel.__init__(self)
|
||||
self.geometry(geometry)
|
||||
self.title(title)
|
||||
self.exit = False
|
||||
self.my_message = message
|
||||
self.my_title = title
|
||||
self.messageLabel = tk.Label(self, text=message, bg="#222", fg="#fff", font="TkFixedFont")
|
||||
self.messageLabel.pack(expand=True, fill=tk.BOTH)
|
||||
|
||||
daemon = Thread(target=self.stream_stdin)
|
||||
daemon.start()
|
||||
self.update_timer()
|
||||
self.mainloop()
|
||||
|
||||
def update_message(self, message):
|
||||
self.messageLabel.configure(text=message)
|
||||
|
||||
def update_title(self, title):
|
||||
self.title(title)
|
||||
|
||||
def update_timer(self):
|
||||
if self.exit:
|
||||
self.quit()
|
||||
return
|
||||
self.messageLabel.configure(text=self.my_message)
|
||||
self.update()
|
||||
self.after(333, self.update_timer)
|
||||
|
||||
def stream_stdin(self):
|
||||
with open(sys.stdin.fileno(), mode="rt", encoding="utf-8", newline=None, buffering=1, closefd=True) as fp:
|
||||
for line in fp:
|
||||
self.my_message = line.rstrip("\r\n")
|
||||
self.exit = True
|
||||
|
||||
class ListBox(tk.Toplevel):
|
||||
def __init__(self, title="", message="", geometry="800x800"):
|
||||
tk.Toplevel.__init__(self)
|
||||
self.geometry(geometry) # Must change these accordingly
|
||||
self.configure(background='#222')
|
||||
self.title(title)
|
||||
self.messageLabel = tk.Label(self, text=message, bg="#222", fg="#fff", font="TkFixedFont")
|
||||
self.choose = tk.Listbox(self,bg="#222", fg="#fff", font="TkFixedFont",selectmode='browse')
|
||||
with open(sys.stdin.fileno(), mode="rt", encoding="utf-8", newline=None, buffering=1, closefd=True) as fp:
|
||||
for i,line in enumerate(fp):
|
||||
self.choose.insert(i,line.rstrip("\r\n"))
|
||||
self.last_element = i
|
||||
self.choose.select_set(0)
|
||||
|
||||
self.labelframe = tk.Frame(self, bg='#222')
|
||||
self.cancel_b = tk.Button(self.labelframe, text = "Cancel", command = self.quit)
|
||||
self.ok_b = tk.Button(self.labelframe, text = "OK", command = self.selected)
|
||||
|
||||
self.messageLabel.pack()#expand=True, fill=tk.BOTH)
|
||||
self.choose.pack(expand=True,fill=tk.BOTH)
|
||||
self.cancel_b.pack(side='left')
|
||||
self.ok_b.pack(side='right')
|
||||
self.labelframe.pack()
|
||||
self.choose.focus_set()
|
||||
self.choose.bind('<Return>', self.selected)
|
||||
self.choose.bind('<Double-Button-1>', self.selected)
|
||||
self.choose.bind("<Key>", self.key_handler)
|
||||
|
||||
self.ok_b.bind('<Return>', self.selected)
|
||||
self.cancel_b.bind('<Return>', self.handle_exit)
|
||||
self.bind_all('<Control-c>', self.handle_exit)
|
||||
self.bind_all('<Escape>', self.handle_exit)
|
||||
|
||||
self.mainloop()
|
||||
|
||||
def set_position(self,index):
|
||||
index = max(0, min( self.last_element, index ))
|
||||
self.choose.selection_clear(0,tk.END)
|
||||
self.choose.activate(index)
|
||||
self.choose.selection_set(index)
|
||||
|
||||
def key_handler(self,event):
|
||||
if len(event.char) == 1 and event.char.isalnum():
|
||||
# ~ print(event.char, event.keysym, event.keycode)
|
||||
for i in list(range(self.choose.curselection()[0] + 1, self.last_element+1)) + list(range(0,self.choose.curselection()[0]+1)):
|
||||
if self.choose.get(i).lower().startswith(event.char):
|
||||
self.set_position(i)
|
||||
return
|
||||
if event.keysym == 'Up':
|
||||
self.set_position(self.choose.curselection()[0] )
|
||||
if event.keysym == 'Down':
|
||||
self.set_position(self.choose.curselection()[0] )
|
||||
if event.keysym == 'Next':
|
||||
self.set_position(self.choose.curselection()[0] +10 )
|
||||
if event.keysym == 'Prior':
|
||||
self.set_position(self.choose.curselection()[0] -10 )
|
||||
if event.keysym == 'Home':
|
||||
self.set_position(0)
|
||||
if event.keysym == 'End':
|
||||
self.set_position(self.last_element)
|
||||
|
||||
def selected(self, *args):
|
||||
for i in self.choose.curselection():
|
||||
print(self.choose.get(i), end='')
|
||||
self.quit()
|
||||
|
||||
def handle_exit(self, *args):
|
||||
self.quit()
|
||||
|
||||
|
||||
def get_opts():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--title",
|
||||
action="store",
|
||||
default=None,
|
||||
help="Window title",
|
||||
)
|
||||
parser.add_argument("--text", action="store", default=None, help="Description text", nargs="?")
|
||||
parser.add_argument("--geometry", action="store", default=None, help="Geometry (not valid for all commands), ex. 800x200+50+50", nargs="?")
|
||||
parser.add_argument(
|
||||
"mode",
|
||||
action="store",
|
||||
default="info",
|
||||
const="info",
|
||||
nargs="?",
|
||||
choices=["info", "password", "entry", "stream","list"],
|
||||
help="operation mode. Note: stream mode expects stdin to update text and line starting with #.",
|
||||
)
|
||||
parsed = parser.parse_args()
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
def set_defaults(opts, title, text, geometry=None):
|
||||
if opts.text is None:
|
||||
opts.text = text
|
||||
if opts.title is None:
|
||||
opts.title = title
|
||||
if opts.geometry is None:
|
||||
opts.geometry = geometry
|
||||
return opts
|
||||
|
||||
|
||||
def main():
|
||||
opts = get_opts()
|
||||
tk.Tk().withdraw()
|
||||
if opts.mode == "password":
|
||||
opts = set_defaults(opts, "Password", "Type password:")
|
||||
pw = tkinter.simpledialog.askstring(opts.title, opts.text, show="*")
|
||||
print(pw, end="")
|
||||
if opts.mode == "info":
|
||||
opts = set_defaults(opts, "Info", "Message")
|
||||
tkinter.messagebox.showinfo(title=opts.title, message=opts.text)
|
||||
if opts.mode == "entry":
|
||||
opts = set_defaults(opts, "Entry", "Type message:")
|
||||
msg = tkinter.simpledialog.askstring(title=opts.title, prompt=opts.text)
|
||||
print(msg, end="")
|
||||
if opts.mode == "stream":
|
||||
opts = set_defaults(opts, "Info", "", "800x80-50-50")
|
||||
StdinBox(title=opts.title, message=opts.text, geometry=opts.geometry)
|
||||
if opts.mode == "list":
|
||||
opts = set_defaults(opts, "Select", "Select from list:")
|
||||
ListBox(title=opts.title, message=opts.text)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user