Skip to content

Instantly share code, notes, and snippets.

@Und3rf10w
Created December 17, 2023 06:07
Show Gist options
  • Save Und3rf10w/f0b827cb4db7a3404764ac3c5267957d to your computer and use it in GitHub Desktop.
Save Und3rf10w/f0b827cb4db7a3404764ac3c5267957d to your computer and use it in GitHub Desktop.
Shitty tkinter overlay that diplays over all other apps that aren't fullscreen. Importable.
import tkinter as tk
from queue import Queue, Empty
import logging
import threading
import sys
# Configure stream redirection as a context manager
class StdoutRedirector:
def __init__(self, write_func):
self.write_func = write_func
self.original_stdout = sys.stdout
def __enter__(self):
sys.stdout = self
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self.original_stdout
def write(self, message):
self.write_func(message)
def flush(self): # Required for maintaining compatibility with sys.stdout
pass
class QueueHandler(logging.Handler):
"""Logging handler that enqueues logs to the provided queue."""
def __init__(self, log_queue):
super().__init__()
self.log_queue = log_queue
def emit(self, record):
log_entry = self.format(record)
self.log_queue.put(log_entry)
# Define the Overlay class that manages the Tkinter window and text display
class Overlay:
def __init__(self):
self.root = tk.Tk()
self.root.title("Overlay Console")
self.root.attributes('-topmost', True)
self.root.overrideredirect(True)
self.root.attributes('-alpha', 0.5)
# Position window
window_width = 500
window_height = 100
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x_coor = screen_width - window_width
y_coor = screen_height - window_height
self.root.geometry(f"{window_width}x{window_height}+{x_coor}+{y_coor}")
# Text widget to show console output
self.text_widget = tk.Text(self.root, bg='black', fg='white')
self.text_widget.pack(fill=tk.BOTH, expand=True)
# Message queue for logs and stdout
self.message_queue = Queue()
# Set up logging to use the queue
self.setup_logging()
def setup_logging(self):
queue_handler = QueueHandler(self.message_queue)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
queue_handler.setFormatter(formatter)
logger = logging.getLogger()
logger.addHandler(queue_handler)
logger.setLevel(logging.DEBUG)
def start(self):
# Start the periodic update for the text widget
self.root.after(2000, self.poll_queue)
self.root.mainloop()
def poll_queue(self):
# Check the queue for new messages and update the text widget
try:
while True:
line = self.message_queue.get_nowait()
self.text_widget.insert(tk.END, line + '\n')
self.text_widget.see(tk.END)
except Empty:
pass
# Schedule next poll
self.root.after(100, self.poll_queue)
# USAGE: Import Overlay, and use this in your main module
# def after_start():
# # Do some code here, but call your `main()` function in a nonblocking fashion so it's in the same thread.
# print("ayylmao")
# if __name__ == "__main__":
# overlay = Overlay()
# with StdoutRedirector(overlay.message_queue.put):
# overlay.root.after(2000, after_start)
# overlay.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment