here2share

# tk_auto_script.py

Sep 3rd, 2025
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 17.18 KB | None | 0 0
  1. # tk_auto_script.py
  2.  
  3. import tkinter as tk
  4. from tkinter import filedialog, colorchooser
  5. import re
  6. from PIL import ImageGrab, ImageTk, Image
  7. import zlib
  8. import base64
  9.  
  10. def create_scrollable_frame(parent):
  11.     canvas = tk.Canvas(parent, bg='black')
  12.     scrollbar = tk.Scrollbar(parent, orient="vertical", command=canvas.yview)
  13.     frame = tk.Frame(canvas)
  14.     frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
  15.     canvas.create_window((0, 0), window=frame, anchor="nw")
  16.     canvas.configure(yscrollcommand=scrollbar.set)
  17.     canvas.pack(side="left", fill="both", expand=True)
  18.     scrollbar.pack(side="right", fill="y")
  19.     canvas.bind_all("<MouseWheel>", lambda e: canvas.yview_scroll(int(-1*(e.delta/120)), "units"))
  20.     return canvas, frame
  21.  
  22. def create_topwindow(title, geometry=None):
  23.     window = tk.Toplevel(root)
  24.     window.title(title)
  25.     if geometry: window.geometry(geometry)
  26.     window.transient(root)
  27.     window.grab_set()
  28.     return window
  29.  
  30. def create_label(parent, text, bg, fg, **kwargs):
  31.     label = tk.Label(parent, text=text, bg=bg, fg=fg, bd=0, padx=2, **kwargs)
  32.     label.pack(side=tk.LEFT)
  33.     return label
  34.  
  35. def setup_bindings(widget, block_name=None, is_editable=False):
  36.     if is_editable:
  37.         widget.bind("<Button-1>", on_editable_click)
  38.     else:
  39.         widget.bind("<Button-1>", lambda e, name=block_name: toggle_feature(name))
  40.     widget.bind("<Button-3>", show_widget_options_menu)
  41.  
  42. # Data Management
  43. def extract_segment_value(segment, matched_type):
  44.     if matched_type in ('text', 'bg', 'fg', 'append'):
  45.         return segment.split("'")[1]
  46.     elif matched_type in ('x', 'y'):
  47.         return segment.split("=")[1]
  48.     elif matched_type == 'geometry':
  49.         return segment.split("'")[1]
  50.     return segment
  51.  
  52. def update_template_block(block_name, old_segment, new_segment):
  53.     for i, line in enumerate(template_blocks[block_name]['lines']):
  54.         if old_segment in line:
  55.             template_blocks[block_name]['lines'][i] = line.replace(old_segment, new_segment)
  56.             break
  57.     template_blocks[block_name]['content'] = '\n'.join(template_blocks[block_name]['lines'])
  58.  
  59. def get_block_colors(block_name):
  60.     enabled = template_blocks[block_name]['enabled']
  61.     return ('black', '#009900') if enabled else ('#990000', 'red')
  62.  
  63. # Editor Functions
  64. def create_line_frame(block_name, bg):
  65.     frame = tk.Frame(scrollable_frame, bg=bg, bd=0, relief='flat', width=1400)
  66.     frame.pack(fill=tk.X, expand=True, pady=0)
  67.     frame.block_name = block_name
  68.     setup_bindings(frame, block_name)
  69.     return frame
  70.  
  71. def create_segment_label(parent, segment, match, block_name, label_bg, editable_bg):
  72.     if match:
  73.         matched_type = next(k for k,v in match.groupdict().items() if v)
  74.         current_value = extract_segment_value(segment, matched_type)
  75.         label = create_label(parent, segment, editable_bg, 'white')
  76.         label.segment_info = {
  77.             'full_text': segment,
  78.             'segment': segment,
  79.             'current_value': current_value,
  80.             'type': type_map[matched_type],
  81.             'block_name': block_name
  82.         }
  83.         return label, True
  84.     return create_label(parent, segment, label_bg, 'white', anchor='w'), False
  85.  
  86. def insert_line(text, block_name):
  87.     label_bg, editable_bg = get_block_colors(block_name)
  88.     line_frame = create_line_frame(block_name, label_bg)
  89.    
  90.     for segment in filter(None, re.split(pattern, text)):
  91.         match = re.fullmatch(pattern, segment)
  92.         label, is_editable = create_segment_label(line_frame, segment, match, block_name, label_bg, editable_bg)
  93.         setup_bindings(label, block_name, is_editable)
  94.  
  95. # Picker Dialogs
  96. def create_picker_window(title, geometry):
  97.     window = create_topwindow(title, geometry)
  98.     window.transient(root)
  99.     window.grab_set()
  100.     return window
  101.  
  102. def add_standard_controls(window, callback):
  103.     frame = tk.Frame(window)
  104.     frame.pack(pady=5)
  105.     tk.Label(frame, text="Custom:").pack(side=tk.LEFT)
  106.     entry = tk.Entry(frame, width=30)
  107.     entry.pack(side=tk.LEFT, padx=5)
  108.     tk.Button(frame, text="Apply", command=lambda: [callback(entry.get()), window.destroy()]).pack(side=tk.LEFT)
  109.     return entry
  110.  
  111. def show_color_picker(segment_info, label):
  112.     def apply_color(val):
  113.         update_segment(label, val)
  114.         window.destroy()
  115.  
  116.     window = create_picker_window("Choose Color", "800x400+0+0")
  117.     current_color = segment_info['current_value']
  118.    
  119.     tk.Label(window, text=f"Current: {current_color}", bg=current_color).pack(pady=10)
  120.    
  121.     grid_frame = tk.Frame(window)
  122.     grid_frame.pack(pady=2)
  123.    
  124.     for i, (name, hex_val) in enumerate(colors.items()):
  125.         if i % 8 == 0:
  126.             row_frame = tk.Frame(grid_frame)
  127.             row_frame.pack()
  128.         btn = tk.Button(row_frame, bg=hex_val, width=9, height=1, command=lambda v=hex_val: apply_color(v))
  129.         btn.pack(side=tk.LEFT, padx=5, pady=5)
  130.  
  131.     entry = add_standard_controls(window, apply_color)
  132.     tk.Button(window, text="System Picker", command=lambda: apply_color(colorchooser.askcolor()[1] or current_color)).pack(pady=10)
  133.  
  134. def show_window_size_picker(segment_info, label):
  135.     def apply_size(size):
  136.         update_segment(label, size)
  137.         window.destroy()
  138.  
  139.     window = create_picker_window("Window Size", "300x200")
  140.     tk.Label(window, text=f"Current: {segment_info['current_value']}").pack(pady=5)
  141.    
  142.     grid_frame = tk.Frame(window)
  143.     grid_frame.pack(pady=5)
  144.     for i, size in enumerate(presets):
  145.         btn = tk.Button(grid_frame, text=size, width=10, command=lambda s=size: apply_size(s))
  146.         btn.grid(row=i//3, column=i%3, padx=2, pady=2)
  147.  
  148.     add_standard_controls(window, apply_size)
  149.  
  150. # Core Operations
  151. def clear_editor():
  152.     for widget in scrollable_frame.winfo_children():
  153.         widget.destroy()
  154.     canvas.delete("bg_rect")
  155.  
  156. def refresh_editor():
  157.     clear_editor()
  158.     for block_name in template_blocks:
  159.         for line in template_blocks[block_name]['lines']:
  160.             insert_line(line, block_name)
  161.         tk.Frame(scrollable_frame, height=10, bg='black').pack(fill=tk.X, pady=0)
  162.     draw_buffer()
  163.  
  164. def update_segment(label, new_value):
  165.     segment_info = label.segment_info
  166.     old_segment = segment_info['segment']
  167.     block_name = segment_info['block_name']
  168.    
  169.     if segment_info['type'] == 'text':
  170.         new_segment = f"text='{new_value}'" if "text='" in old_segment else f"append('{new_value}')"
  171.     elif segment_info['type'] == 'coord':
  172.         new_segment = f"x={new_value}" if 'x=' in old_segment else f"y={new_value}"
  173.     elif segment_info['type'] == 'color':
  174.         new_segment = f"bg='{new_value}'" if 'bg=' in old_segment else f"fg='{new_value}'"
  175.     elif segment_info['type'] in ('geometry', 'window'):
  176.         new_segment = f"{segment_info['type']}({new_value}+0+0)"
  177.     else: return
  178.    
  179.     update_template_block(block_name, old_segment, new_segment)
  180.     label.config(text=new_segment)
  181.     label.segment_info.update({
  182.         'segment': new_segment,
  183.         'current_value': new_value
  184.     })
  185.  
  186. def show_widget_options_menu(event):
  187.     widget = event.widget
  188.     parent = widget.master
  189.    
  190.     if not hasattr(parent, 'block_name'):
  191.         return
  192.    
  193.     widget_type = parent.block_name.split()[0]
  194.     current_lines = template_blocks[parent.block_name]['lines']
  195.     widget_options = WIDGET_OPTIONS['widget_specific'].get(widget_type, [])
  196.     if not widget_options:
  197.         return
  198.    
  199.     window = create_topwindow(f"{widget_type} Options")
  200.     listbox = tk.Listbox(window, selectmode=tk.MULTIPLE, height=30, width=30)
  201.     scrollbar = tk.Scrollbar(window)
  202.     scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  203.     listbox.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
  204.     listbox.config(yscrollcommand=scrollbar.set)
  205.     scrollbar.config(command=listbox.yview)
  206.    
  207.     for option in widget_options:
  208.         listbox.insert(tk.END, option)
  209.         if any(option in line for line in current_lines):
  210.             listbox.selection_set(tk.END)
  211.    
  212.     tk.Button(window, text="Apply", command=lambda: [window.destroy(), update_editor_content()]).pack(side=tk.BOTTOM, fill=tk.X)
  213.  
  214. def update_editor_content():
  215.     clear_editor()
  216.     for block_name in template_blocks:
  217.         for line in template_blocks[block_name]['lines']:
  218.             insert_line(line, block_name)
  219.         tk.Frame(scrollable_frame, height=10, bg='black').pack(fill=tk.X, pady=0)
  220.     draw_buffer()
  221.  
  222. def toggle_feature(name):
  223.     template_blocks[name]['enabled'] = not template_blocks[name]['enabled']
  224.     for child in scrollable_frame.winfo_children():
  225.         if hasattr(child, 'block_name') and child.block_name == name:
  226.             label_bg, editable_bg = ('black', '#009900') if template_blocks[name]['enabled'] else ('#990000', 'red')
  227.             child.configure(bg=label_bg)
  228.             for sub in child.winfo_children():
  229.                 if hasattr(sub, 'segment_info'):
  230.                     sub.configure(bg=editable_bg)
  231.                 else:
  232.                     sub.configure(bg=label_bg)
  233.     do_buffer()
  234.  
  235. def run_script():
  236.     try:
  237.         full_script = ""        
  238.         for block_name in template_blocks:
  239.             if template_blocks[block_name]['enabled']:
  240.                 full_script += template_blocks[block_name]['content'] + "\n\n"
  241.         exec(full_script, {"tk": tk})
  242.     except Exception as e:
  243.         print(f"Error: {e}")
  244.  
  245. def save_script():
  246.     file = filedialog.asksaveasfilename(defaultextension=".py")
  247.     if file:
  248.         full_script = ""
  249.         for block_name in template_blocks:
  250.             if template_blocks[block_name]['enabled']:
  251.                 full_script += template_blocks[block_name]['content'] + "\n\n"
  252.         with open(file, "w") as f:
  253.             f.write(full_script)
  254.            
  255. def draw_buffer():
  256.     root.update_idletasks()
  257.     def grab_and_display():
  258.         x = canvas.winfo_rootx()
  259.         y = canvas.winfo_rooty()
  260.         w = canvas.winfo_width()
  261.         h = canvas.winfo_height()
  262.         x *= x_offset
  263.         y *= y_offset
  264.         w = x + w + w_offset
  265.         h = y + h + h_offset
  266.         img = ImageGrab.grab(bbox=(x, y, w, h))
  267.         img = img.resize((canvas.winfo_width(), canvas.winfo_height()))
  268.         canvas.tk_img = ImageTk.PhotoImage(img)
  269.     root.after(250, grab_and_display)
  270.  
  271. def do_buffer():
  272.     overlay = tk.Label(canvas, image=canvas.tk_img)
  273.     overlay.place(x=0, y=0, relwidth=1, relheight=1)
  274.     draw_buffer()
  275.     root.after(100, overlay.destroy)
  276.  
  277. x_offset = 1.5
  278. y_offset = 1.51
  279. w_offset = 592
  280. h_offset = 302
  281.  
  282. def on_editable_click(event):
  283.     label = event.widget
  284.     segment_info = label.segment_info
  285.  
  286.     if segment_info['type'] == 'color':
  287.         show_color_picker(segment_info, label)
  288.     elif segment_info['type'] in ('coord', 'geometry'):
  289.         show_window_size_picker(segment_info, label)
  290.     else:
  291.         window = create_topwindow("Edit Value", "300x150")
  292.         tk.Label(window, text=f"Edit {segment_info['type']}:").pack(pady=5)
  293.         entry = tk.Entry(window, width=100)
  294.         entry.insert(0, segment_info['current_value'])
  295.         entry.pack(pady=5)
  296.         entry.focus_set()
  297.         tk.Button(window, text="Save", command=lambda: [update_segment(label, entry.get()), window.destroy()]).pack(pady=5)
  298.    
  299.     label.master.bind("<Button-1>", lambda e, name=segment_info['block_name']: toggle_feature(name))
  300.  
  301. root = tk.Tk()
  302. root.title("GUI Script Builder")
  303. root.geometry("1200x640+0+0")
  304.  
  305. script = '''
  306. # Geometry
  307. root = tk.Tk()
  308. root.geometry('1200x640')
  309.  
  310. # Label
  311. tk.Label(root, text='text', bg='red', fg='white').place(x=10, y=10)
  312.  
  313. # Entry
  314. tk.Entry(root, bg='red', fg='white').place(x=10, y=40)
  315.  
  316. # Button
  317. tk.Button(root, text='text', bg='red', fg='white').place(x=10, y=70)
  318.  
  319. # Clipboard
  320. def copy_text(data):
  321.    root.clipboard_clear()
  322.    root.clipboard_append(data)
  323. def paste_text():
  324.    return root.clipboard_get()
  325.  
  326. # Mouse
  327. def on_mouse_click(event):
  328.    return event.x, event.y
  329. root.bind('<Button-1>', on_mouse_click)
  330.  
  331. # Keyboard
  332. def on_key(event):
  333.    return event.char
  334. root.bind('<Key>', on_key)
  335. '''
  336.  
  337. template_blocks = {}
  338. for block in script.strip().split('# ')[1:]:
  339.     if '\n' in block:
  340.         header, content = block.split('\n', 1)
  341.         header = header.strip()
  342.         content = '# ' + header + '\n' + content
  343.     else:
  344.         header = block.strip()
  345.         content = '# ' + header
  346.    
  347.     if header:
  348.         template_blocks[header] = {
  349.             'content': content,
  350.             'enabled': True,
  351.             'lines': content.split('\n')
  352.         }
  353.  
  354. pattern = r"(?P<text>text='[^']*')|(?P<x>x=\d+)|(?P<y>y=\d+)|" \
  355.           r"(?P<bg>bg='[^']*')|(?P<fg>fg='[^']*')|" \
  356.           r"(?P<append>append\('[^']*'\))|" \
  357.           r"(?P<geometry>geometry\('[^']*'\))|" \
  358.           r"(?P<toplevel>[\w]+ = tk\.Toplevel\(.*?\))"
  359.          
  360. presets = "600x400", "800x600", "1024x768", "1200x640", "1400x700", "1920x1080"
  361.  
  362. colors = {
  363.     "red": "#FF0000", "green": "#00FF00", "blue": "#0000FF",
  364.     "yellow": "#FFFF00", "cyan": "#00FFFF", "magenta": "#FF00FF",
  365.     "black": "#000000", "white": "#FFFFFF", "violet": "#8F00FF",
  366.     "orange": "#FFA500", "purple": "#800080", "brown": "#A52A2A",
  367.     "pink": "#FFC0CB", "lime": "#00FF00", "navy": "#000080",
  368.     "teal": "#008080", "maroon": "#800000", "olive": "#808000",
  369.     "light gray": "#F0F0ED", "dark gray": "#A9A9A9",
  370.     "silver": "#C0C0C0", "dim gray": "#696969",
  371.     "slate gray": "#708090", "light slate": "#778899"
  372. }
  373.  
  374. type_map = {
  375.     'text': 'text',
  376.     'x': 'coord',
  377.     'y': 'coord',
  378.     'bg': 'color',
  379.     'fg': 'color',
  380.     'append': 'text',
  381.     'geometry': 'geometry',
  382.     'toplevel': 'window'
  383. }
  384.  
  385. WIDGET_OPTIONS = {
  386.     'widget_specific': {
  387.         'Button': [
  388.             'command', 'default', 'height', 'overrelief', 'repeatdelay',
  389.             'repeatinterval', 'width'
  390.         ],
  391.         'Canvas': [
  392.             'closeenough', 'confine', 'scrollregion', 'xscrollcommand',
  393.             'yscrollcommand', 'xscrollincrement', 'yscrollincrement'
  394.         ],
  395.         'Checkbutton': [
  396.             'command', 'indicatoron', 'offvalue', 'onvalue', 'selectcolor',
  397.             'selectimage', 'variable'
  398.         ],
  399.         'Entry': [
  400.             'exportselection', 'invalidcommand', 'justify', 'readonlybackground',
  401.             'show', 'validate', 'validatecommand', 'xscrollcommand'
  402.         ],
  403.         'Frame': [
  404.             'container', 'height', 'width'
  405.         ],
  406.         'Label': [
  407.             'height', 'wraplength'
  408.         ],
  409.         'LabelFrame': [
  410.             'labelanchor', 'text'
  411.         ],
  412.         'Listbox': [
  413.             'activestyle', 'exportselection', 'height', 'listvariable',
  414.             'selectmode', 'width', 'xscrollcommand', 'yscrollcommand'
  415.         ],
  416.         'Menu': [
  417.             'postcommand', 'tearoff', 'tearoffcommand', 'title', 'type'
  418.         ],
  419.         'Menubutton': [
  420.             'direction', 'indicatoron', 'state'
  421.         ],
  422.         'Message': [
  423.             'aspect', 'justify'
  424.         ],
  425.         'OptionMenu': [
  426.             'command', 'value'
  427.         ],
  428.         'PanedWindow': [
  429.             'handlepad', 'handlesize', 'opaqueresize', 'orient', 'sashcursor',
  430.             'sashpad', 'sashrelief', 'sashwidth', 'showhandle'
  431.         ],
  432.         'Radiobutton': [
  433.             'command', 'indicatoron', 'selectcolor', 'selectimage', 'value',
  434.             'variable'
  435.         ],
  436.         'Scale': [
  437.             'bigincrement', 'command', 'digits', 'from_', 'label', 'length',
  438.             'resolution', 'showvalue', 'sliderlength', 'sliderrelief',
  439.             'tickinterval', 'to', 'variable'
  440.         ],
  441.         'Scrollbar': [
  442.             'activerelief', 'command', 'elementborderwidth'
  443.         ],
  444.         'Spinbox': [
  445.             'buttonbackground', 'buttoncursor', 'buttondownrelief', 'buttonuprelief',
  446.             'command', 'format', 'from_', 'increment', 'invalidcommand',
  447.             'values', 'wrap'
  448.         ],
  449.         'Text': [
  450.             'autoseparators', 'blockcursor', 'endline', 'height',
  451.             'inactiveselectbackground', 'maxundo', 'spacing1', 'spacing2',
  452.             'spacing3', 'startline', 'tabs', 'tabstyle', 'undo', 'width',
  453.             'wrap', 'xscrollcommand', 'yscrollcommand'
  454.         ],
  455.         'Toplevel': [
  456.             'container', 'menu', 'screen', 'use'
  457.         ],
  458.         'Treeview': [
  459.             'columns', 'displaycolumns', 'height', 'selectmode', 'show'
  460.         ],
  461.         'Progressbar': [
  462.             'orient', 'length', 'mode', 'maximum', 'value', 'variable'
  463.         ],
  464.         'Separator': [
  465.             'orient'
  466.         ],
  467.         'Sizegrip': [],
  468.         'Notebook': [
  469.             'height', 'padding', 'width'
  470.         ],
  471.         'Combobox': [
  472.             'exportselection', 'justify', 'postcommand', 'state', 'textvariable',
  473.             'values', 'width'
  474.         ]
  475.     }
  476. }
  477.  
  478. button_frame = tk.Frame(root)
  479. button_frame.pack(fill=tk.X, padx=5, pady=5)
  480.  
  481. tk.Button(button_frame, text="Run Code", command=run_script).pack(side=tk.LEFT, padx=5)
  482. tk.Button(button_frame, text="Save Script", command=save_script).pack(side=tk.LEFT, padx=5)
  483.  
  484. editor_frame = tk.Frame(root)
  485. editor_frame.pack(fill=tk.BOTH, expand=True)
  486.  
  487. canvas, scrollable_frame = create_scrollable_frame(editor_frame)
  488. canvas.bind("<Button-3>", show_widget_options_menu)
  489. canvas.tk_img = None
  490.  
  491. update_editor_content()
  492. root.mainloop()
Add Comment
Please, Sign In to add comment