print ("Welcom to Python OS !")
print ("Chose a Version of Python OS:")
print (" 1 = Python 9")
print (" 2 = Python 10")
print (" 3 = Python 11")
print (" 4 = Python 12")
x = int(input("Enter Number (1-4):"))
if x == 1 :
import tkinter as tk
from tkinter import messagebox, filedialog, colorchooser
import os, time, platform, subprocess, json, math, zipfile, shutil, tempfile, re, urllib.request, threading
class PythonOS:
def __init__(self, root):
self.root = root
self.root.title("Python OS 9.0")
self.root.geometry("1366x768")
self.root.minsize(1050, 650)
self.wallpaper = "#0078d7"
self.username = "User"
self.notifications = []
self.wallpaper_image = None
self.windows = []
self.tasks = []
self.start_open = False
self.menu = None
self.power_menu = None
self.desktop_icons = []
self.alt_tab_index = 0
self.settings_file = os.path.join(os.path.expanduser("~"), ".python_os_settings.json")
self.apps_dir = os.path.join(os.path.expanduser("~"), ".python_os_apps")
self.apps_data = os.path.join(self.apps_dir, "installed")
self.catalog_file = os.path.join(self.apps_dir, "catalog.json")
os.makedirs(self.apps_data, exist_ok=True)
self.load_settings()
self.boot()
# ---------- startup ----------
def load_settings(self):
try:
with open(self.settings_file, "r", encoding="utf-8") as f:
d = json.load(f)
self.wallpaper = d.get("wallpaper", self.wallpaper)
self.username = d.get("username", "User")
except Exception:
pass
def save_settings(self):
try:
with open(self.settings_file, "w", encoding="utf-8") as f:
json.dump({"wallpaper": self.wallpaper, "username": self.username}, f)
except Exception:
pass
def boot(self):
self.clear()
self.root.configure(bg="#080808")
box = tk.Frame(self.root, bg="#080808")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#080808",
font=("Segoe UI", 80)).pack(pady=(150, 0))
tk.Label(box, text="Python OS", fg="white", bg="#080808",
font=("Segoe UI", 28, "bold")).pack()
tk.Label(box, text="Loading desktop...", fg="#aaa", bg="#080808",
font=("Segoe UI", 10)).pack(pady=12)
bar = tk.Frame(box, bg="#333", width=300, height=5)
bar.pack()
bar.pack_propagate(False)
fill = tk.Frame(bar, bg="#1683d8", width=0, height=5)
fill.pack(side="left")
def animate(n=0):
if n <= 300 and box.winfo_exists():
fill.config(width=n)
self.root.after(7, lambda: animate(n + 4))
animate()
self.root.after(1500, self.login)
def login(self):
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 65)).pack(pady=(115, 0))
tk.Label(box, text="Python OS", fg="white", bg="#176aa5",
font=("Segoe UI", 27, "bold")).pack()
card = tk.Frame(box, bg="white", width=350, height=190)
card.pack(pady=22)
card.pack_propagate(False)
tk.Label(card, text="👤", bg="white", font=("Segoe UI Emoji", 30)).pack(pady=12)
tk.Label(card, text="User", bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack()
b = tk.Button(card, text="Sign in", command=self.desktop,
bg="#0878c9", fg="white", relief="flat",
font=("Segoe UI", 11, "bold"), padx=38, pady=7)
b.pack(pady=12)
self.root.bind("<Return>", lambda e: self.desktop())
def clear(self):
for w in self.root.winfo_children():
w.destroy()
# ---------- desktop ----------
def desktop(self):
self.root.unbind("<Return>")
self.clear()
self.root.bind_all("<Control-Alt-d>", lambda e: self.show_desktop())
self.root.bind_all("<Control-Alt-r>", lambda e: self.open_run())
self.root.bind_all("<Control-Alt-t>", lambda e: self.terminal())
self.root.bind_all("<Control-Alt-l>", lambda e: self.lock_screen())
self.root.bind_all("<Alt-KeyPress-Tab>", self.alt_tab)
self.root.bind_all("<Control-Alt-s>", lambda e: self.power_menu_open())
self.root.configure(bg=self.wallpaper)
self.desktop_frame = tk.Frame(self.root, bg=self.wallpaper)
self.desktop_frame.pack(fill="both", expand=True)
if self.wallpaper_image:
self._wall_img_label = tk.Label(self.desktop_frame, image=self.wallpaper_image, bd=0)
self._wall_img_label.place(relx=0, rely=0, relwidth=1, relheight=1)
self._wall_img_label.lower()
# wallpaper branding
tk.Label(self.desktop_frame, text="Python OS",
bg=self.wallpaper, fg="white",
font=("Segoe UI", 40, "bold")).place(relx=.5, rely=.40, anchor="center")
tk.Label(self.desktop_frame, text="Version 9.0",
bg=self.wallpaper, fg="#d9efff",
font=("Segoe UI", 11)).place(relx=.5, rely=.48, anchor="center")
icons = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("⚙", "Settings", self.settings),
("💻", "Terminal", self.terminal),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
]
for i, item in enumerate(icons):
x = 22 + (i // 6) * 105
y = 20 + (i % 6) * 92
self.icon(*item, x=x, y=y)
# taskbar
self.taskbar = tk.Frame(self.root, bg="#1f1f1f", height=48)
self.taskbar.pack(side="bottom", fill="x")
self.taskbar.pack_propagate(False)
tk.Button(self.taskbar, text="⊞", command=self.toggle_start,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 23)).pack(side="left", padx=6)
tk.Button(self.taskbar, text="🔍", command=self.search,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 13)).pack(side="left", padx=3)
self.task_area = tk.Frame(self.taskbar, bg="#1f1f1f")
self.task_area.pack(side="left", fill="both", expand=True, padx=8)
# Windows 10 style pinned taskbar buttons
for text, cmd in [("▣", self.explorer), ("🌐", self.browser), ("🛍", self.app_center)]:
tk.Button(self.taskbar, text=text, command=cmd, bg="#1f1f1f", fg="white",
activebackground="#333333", relief="flat", bd=0,
font=("Segoe UI Emoji", 13)).pack(side="left", padx=2)
tray = tk.Frame(self.taskbar, bg="#202020")
tray.pack(side="right", fill="y")
tk.Button(tray, text="🔔", command=self.notification_center, bg="#202020", fg="white", relief="flat", bd=0).pack(side="left", padx=3)
tk.Button(tray, text="⌁ 🔊", command=self.quick_controls, bg="#202020", fg="white", relief="flat", bd=0,
font=("Segoe UI", 11)).pack(side="left", padx=4)
tk.Button(tray, text="⏻", command=self.power_menu_open, bg="#202020", fg="white",
activebackground="#3b3b3b", relief="flat", bd=0, font=("Segoe UI", 14)).pack(side="left", padx=4)
self.clock = tk.Label(tray, bg="#202020", fg="white",
font=("Segoe UI", 9), justify="right")
self.clock.pack(side="left", padx=10)
self.tick()
self.desktop_frame.bind("<Button-3>", self.context)
self.desktop_frame.bind("<Double-Button-1>", lambda e: self.close_start())
def icon(self, emoji, name, command, x, y):
f = tk.Frame(self.desktop_frame, bg=self.wallpaper, width=92, height=82)
f.place(x=x, y=y)
f.pack_propagate(False)
btn = tk.Button(f, text=emoji, command=command,
bg=self.wallpaper, fg="white", activebackground="#2b89c9",
relief="flat", bd=0, font=("Segoe UI Emoji", 25))
btn.pack(fill="x")
tk.Label(f, text=name, bg=self.wallpaper, fg="white",
font=("Segoe UI", 9), wraplength=88).pack()
self.desktop_icons.append(f)
def start_drag(e):
f._dx, f._dy = e.x, e.y
def drag(e):
nx=max(4, min(self.root.winfo_width()-100, f.winfo_x()+e.x-f._dx))
ny=max(4, min(self.root.winfo_height()-145, f.winfo_y()+e.y-f._dy))
f.place(x=nx, y=ny)
for w in (f, btn):
w.bind("<ButtonPress-1>", start_drag, add="+")
w.bind("<B1-Motion>", drag, add="+")
def quick_controls(self):
win=self.new_window("Quick Settings", "430x300")
tk.Label(win,text="⚡ Quick settings",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=20,pady=18)
for text,cmd in [("🎨 Personalization",self.personalize),("🔔 Notifications",self.notification_center),("⚙ Settings",self.settings),("ℹ About",self.system_info)]:
tk.Button(win,text=text,command=cmd,anchor="w",relief="flat",font=("Segoe UI",11)).pack(fill="x",padx=20,pady=4)
def tick(self):
if hasattr(self, "clock") and self.clock.winfo_exists():
self.clock.config(text=time.strftime("%H:%M\n%d/%m/%Y"))
self.root.after(1000, self.tick)
# ---------- Python OS 9.0 system features ----------
def notify(self, title, text):
self.notifications.append((title, text, time.strftime("%H:%M")))
if len(self.notifications) > 30:
self.notifications = self.notifications[-30:]
def notification_center(self):
win = self.new_window("Notification Center", "520x520")
win.configure(bg="#f4f4f4")
tk.Label(win, text="🔔 Notifications", bg="#f4f4f4", fg="#222",
font=("Segoe UI", 20, "bold")).pack(anchor="w", padx=20, pady=18)
body = tk.Frame(win, bg="#f4f4f4")
body.pack(fill="both", expand=True, padx=14)
if not self.notifications:
tk.Label(body, text="You're all caught up.", bg="#f4f4f4", fg="#777",
font=("Segoe UI", 12)).pack(pady=50)
else:
for title, text, stamp in reversed(self.notifications):
card = tk.Frame(body, bg="white", bd=1, relief="solid")
card.pack(fill="x", pady=5)
tk.Label(card, text=f"{title} • {stamp}", bg="white", fg="#222",
font=("Segoe UI", 11, "bold")).pack(anchor="w", padx=12, pady=(9,2))
tk.Label(card, text=text, bg="white", fg="#555", wraplength=450,
justify="left").pack(anchor="w", padx=12, pady=(0,9))
tk.Button(win, text="Clear notifications", command=lambda:self.clear_notifications(win),
relief="flat").pack(anchor="e", padx=18, pady=12)
def clear_notifications(self, win=None):
self.notifications.clear()
if win and win.winfo_exists():
self.close_window(win)
self.notification_center()
def lock_screen(self):
self.close_start()
for w, _ in list(self.tasks):
try:
if w.winfo_exists(): w.withdraw()
except Exception: pass
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 80)).pack(pady=(125, 0))
tk.Label(box, text=self.username, fg="white", bg="#176aa5",
font=("Segoe UI", 24, "bold")).pack(pady=8)
tk.Label(box, text=time.strftime("%A, %d %B\n%H:%M"), fg="white", bg="#176aa5",
font=("Segoe UI", 18)).pack(pady=10)
b=tk.Button(box, text="🔓 Sign in", command=self.unlock_screen,
font=("Segoe UI", 12, "bold"), padx=30, pady=10)
b.pack(pady=25)
self.root.bind("<Return>", lambda e: self.unlock_screen())
def unlock_screen(self):
self.root.unbind("<Return>")
self.desktop()
self.notify("Python OS", "You signed in successfully.")
def personalize(self):
win=self.new_window("Personalization", "620x470")
tk.Label(win,text="🎨 Personalization",font=("Segoe UI",22,"bold")).pack(anchor="w",padx=20,pady=18)
tk.Label(win,text="Choose your desktop appearance.",fg="#666").pack(anchor="w",padx=20)
row=tk.Frame(win); row.pack(fill="x",padx=20,pady=20)
tk.Button(row,text="Choose color",command=self.choose_wallpaper).pack(side="left",padx=5)
tk.Button(row,text="Choose wallpaper image",command=self.choose_wallpaper_image).pack(side="left",padx=5)
tk.Button(row,text="Reset",command=lambda:self.reset_wallpaper()).pack(side="left",padx=5)
tk.Label(win,text="Keyboard shortcuts",font=("Segoe UI",14,"bold")).pack(anchor="w",padx=20,pady=(15,5))
tk.Label(win,text="Ctrl+Alt+D Show desktop\nCtrl+Alt+R Run\nCtrl+Alt+T Terminal\nCtrl+Alt+L Lock screen",justify="left").pack(anchor="w",padx=20)
def choose_wallpaper(self):
c=colorchooser.askcolor(title="Choose desktop color")
if c and c[1]:
self.wallpaper=c[1]
self.wallpaper_image=None
self.save_settings()
self.desktop()
self.notify("Personalization", "Desktop color changed.")
def choose_wallpaper_image(self):
path=filedialog.askopenfilename(title="Choose wallpaper",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if path:
try:
self.wallpaper_image=tk.PhotoImage(file=path)
self.wallpaper="#000000"
self.save_settings()
self.desktop()
self.notify("Personalization", "Wallpaper image applied.")
except Exception as e:
messagebox.showerror("Wallpaper", f"Could not load image.\n{e}")
def reset_wallpaper(self):
self.wallpaper="#0078d7"
self.wallpaper_image=None
self.save_settings(); self.desktop()
def system_info(self):
win=self.new_window("About Python OS", "560x390")
tk.Label(win,text="⊞ Python OS 9.0",font=("Segoe UI",24,"bold")).pack(pady=25)
info=f"Windows 10 Edition\n\nPython: {platform.python_version()}\nPlatform: {platform.platform()}\nArchitecture: {platform.machine()}\nUser: {self.username}"
tk.Label(win,text=info,justify="left",font=("Segoe UI",11)).pack(anchor="w",padx=35)
# ---------- windows ----------
def new_window(self, title, size="700x480"):
self.close_start()
win = tk.Toplevel(self.root)
win.title(title)
win.geometry(size)
win.minsize(350, 230)
win.protocol("WM_DELETE_WINDOW", lambda: self.close_window(win))
win.bind("<FocusIn>", lambda e: self.focus(win))
self.windows.append(win)
b = tk.Button(self.task_area, text=title[:18], command=lambda: self.focus(win),
bg="#303030", fg="white", activebackground="#505050",
relief="flat", bd=0, font=("Segoe UI", 9), padx=9)
b.pack(side="left", padx=2, pady=6)
self.tasks.append((win, b))
win.focus_force()
return win
def focus(self, win):
if win.winfo_exists():
win.deiconify()
win.lift()
win.focus_force()
def close_window(self, win):
for w, b in list(self.tasks):
if w is win:
b.destroy()
self.tasks.remove((w, b))
if win in self.windows:
self.windows.remove(win)
if win.winfo_exists():
win.destroy()
# ---------- start ----------
def toggle_start(self):
if self.start_open:
self.close_start()
return
self.start_open = True
self.start = tk.Frame(self.root, bg="#f4f4f4", width=620, height=620,
bd=1, relief="solid")
self.start.place(x=6, y=max(5, self.root.winfo_height()-665))
self.start.lift()
head = tk.Frame(self.start, bg="#0078d7", height=76)
head.pack(fill="x")
tk.Label(head, text=f"👤 {self.username}", bg="#0078d7", fg="white",
font=("Segoe UI", 14, "bold")).pack(side="left", padx=20, pady=22)
search = tk.Entry(self.start, font=("Segoe UI", 11))
search.pack(fill="x", padx=16, pady=12)
search.insert(0, "Search apps...")
search.bind("<FocusIn>", lambda e: search.delete(0, "end") if search.get()=="Search apps..." else None)
body = tk.Frame(self.start, bg="#f4f4f4")
body.pack(fill="both", expand=True)
apps = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("💻", "Terminal", self.terminal),
("⚙", "Settings", self.settings),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
]
buttons = []
for ico, name, cmd in apps:
b = tk.Button(body, text=f"{ico} {name}", command=cmd,
anchor="w", bg="#f4f4f4", fg="#222",
activebackground="#dceefa", relief="flat",
font=("Segoe UI", 11), height=2)
b.pack(fill="x", padx=12, pady=1)
buttons.append((name.lower(), b))
def filter_apps(e=None):
q = search.get().lower()
for n, b in buttons:
b.pack_forget()
if q in n:
b.pack(fill="x", padx=12, pady=1)
search.bind("<KeyRelease>", filter_apps)
bottom = tk.Frame(self.start, bg="#e7e7e7", height=48)
bottom.pack(side="bottom", fill="x")
tk.Button(bottom, text="⚙ Settings", command=self.settings,
bg="#e7e7e7", relief="flat").pack(side="left", padx=12, pady=9)
tk.Button(bottom, text="🔒 Lock", command=self.lock_screen,
bg="#e7e7e7", relief="flat").pack(side="right", padx=4, pady=9)
tk.Button(bottom, text="⏻ Shut down", command=self.shutdown,
bg="#e7e7e7", relief="flat").pack(side="right", padx=12, pady=9)
def close_start(self):
if self.start_open and self.start.winfo_exists():
self.start.destroy()
self.start_open = False
# ---------- apps ----------
def explorer(self):
win = self.new_window("File Explorer", "900x560")
toolbar = tk.Frame(win, bg="#eeeeee")
toolbar.pack(fill="x")
path = tk.StringVar(value=os.path.expanduser("~"))
ent = tk.Entry(toolbar, textvariable=path, font=("Segoe UI", 10))
ent.pack(side="left", fill="x", expand=True, padx=6, pady=6)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=6, pady=6)
def load(p):
try:
p = os.path.abspath(os.path.expanduser(p))
items = sorted(os.listdir(p), key=lambda x:(not os.path.isdir(os.path.join(p,x)), x.lower()))
box.delete(0, "end")
for i in items:
box.insert("end", ("📁 " if os.path.isdir(os.path.join(p,i)) else "📄 ")+i)
path.set(p)
except Exception as e:
messagebox.showerror("File Explorer", str(e), parent=win)
def open_item(e=None):
s = box.curselection()
if not s: return
name = box.get(s[0])[2:]
p = os.path.join(path.get(), name)
if os.path.isdir(p):
load(p)
else:
try:
if platform.system()=="Windows": os.startfile(p)
elif platform.system()=="Darwin": subprocess.Popen(["open",p])
else: subprocess.Popen(["xdg-open",p])
except Exception as e:
messagebox.showerror("Open", str(e), parent=win)
tk.Button(toolbar, text="↑", command=lambda:load(os.path.dirname(path.get()))).pack(side="left")
tk.Button(toolbar, text="Go", command=lambda:load(path.get())).pack(side="right", padx=5)
ent.bind("<Return>", lambda e:load(path.get()))
box.bind("<Double-Button-1>", open_item)
load(path.get())
def notepad(self):
win = self.new_window("Notepad", "800x560")
bar = tk.Frame(win, bg="#eeeeee"); bar.pack(fill="x")
text = tk.Text(win, font=("Consolas", 12), undo=True, wrap="word")
text.pack(fill="both", expand=True)
def new(): text.delete("1.0","end")
def openf():
p=filedialog.askopenfilename(parent=win,filetypes=[("Text","*.txt"),("All","*.*")])
if p:
try:
text.delete("1.0","end"); text.insert("1.0",open(p,encoding="utf-8").read())
except Exception as e: messagebox.showerror("Notepad",str(e),parent=win)
def save():
p=filedialog.asksaveasfilename(parent=win,defaultextension=".txt",
filetypes=[("Text","*.txt"),("All","*.*")])
if p: open(p,"w",encoding="utf-8").write(text.get("1.0","end-1c"))
for n,c in [("New",new),("Open",openf),("Save",save)]:
tk.Button(bar,text=n,command=c,relief="flat").pack(side="left",padx=4,pady=4)
def calculator(self):
win=self.new_window("Calculator","380x520")
exp=tk.StringVar()
tk.Entry(win,textvariable=exp,justify="right",font=("Segoe UI",24),bd=0).pack(fill="x",padx=12,pady=15,ipady=8)
grid=tk.Frame(win); grid.pack(fill="both",expand=True,padx=8,pady=8)
keys=[["C","(",")","/"],["7","8","9","*"],["4","5","6","-"],["1","2","3","+"],["0",".","⌫","="]]
def press(k):
if k=="C": exp.set("")
elif k=="⌫": exp.set(exp.get()[:-1])
elif k=="=":
try:
if any(c not in "0123456789.+-*/() " for c in exp.get()): raise ValueError()
exp.set(str(eval(exp.get(),{"__builtins__":{}},{})))
except: exp.set("Error")
else: exp.set(exp.get()+k)
for r,row in enumerate(keys):
for c,k in enumerate(row):
tk.Button(grid,text=k,command=lambda x=k:press(x),
font=("Segoe UI",13),relief="flat").grid(row=r,column=c,sticky="nsew",padx=2,pady=2)
for r in range(5): grid.rowconfigure(r,weight=1)
for c in range(4): grid.columnconfigure(c,weight=1)
def browser(self):
win=self.new_window("Python Browser","760x520")
tk.Label(win,text="🌐 Python Browser",font=("Segoe UI",20,"bold")).pack(pady=18)
tk.Label(win,text="This lightweight browser opens web pages in your default browser.",
fg="#666").pack()
url=tk.Entry(win,font=("Segoe UI",12))
url.pack(fill="x",padx=35,pady=15)
url.insert(0,"https://[Log in to view URL]")
def go():
u=url.get().strip()
if not u.startswith(("http://","https://")): u="https://"+u
try:
import webbrowser; webbrowser.open(u)
except Exception as e: messagebox.showerror("Browser",str(e),parent=win)
tk.Button(win,text="Open website",command=go,width=18).pack()
def settings(self):
win=self.new_window("Settings","700x520")
tk.Label(win,text="Settings",font=("Segoe UI",26,"bold")).pack(anchor="w",padx=25,pady=20)
tk.Label(win,text="Personalization",font=("Segoe UI",13,"bold")).pack(anchor="w",padx=25,pady=5)
colors=[("Windows Blue","#0878c9"),("Dark Blue","#123b63"),("Green","#197a3a"),
("Purple","#663399"),("Dark","#222222")]
def setbg(c):
self.wallpaper=c
self.desktop_frame.config(bg=c)
for w in self.desktop_frame.winfo_children():
try: w.config(bg=c)
except: pass
self.save_settings()
for n,c in colors:
tk.Button(win,text=n,command=lambda c=c:setbg(c),width=24,anchor="w").pack(anchor="w",padx=25,pady=3)
tk.Button(win,text="Choose custom color",
command=lambda:(lambda c:c and setbg(c))(colorchooser.askcolor(parent=win)[1])).pack(anchor="w",padx=25,pady=8)
tk.Label(win,text=f"Python {platform.python_version()} • {platform.system()}",
fg="#777").pack(anchor="w",padx=25,pady=18)
def terminal(self):
win=self.new_window("Terminal","800x500")
out=tk.Text(win,bg="#0c0c0c",fg="#eee",insertbackground="white",font=("Consolas",11))
out.pack(fill="both",expand=True)
out.insert("end","Python OS Terminal 3.0\nType 'help' for commands.\n\n> ")
ent=tk.Entry(win,bg="#0c0c0c",fg="white",insertbackground="white",font=("Consolas",11))
ent.pack(fill="x")
def write(s): out.insert("end",s+"\n"); out.see("end")
def run(e=None):
cmd=ent.get().strip(); ent.delete(0,"end")
if not cmd:return
out.insert("end",cmd+"\n")
if cmd=="help": write("help, clear, time, date, system, pwd, dir, echo <text>, python")
elif cmd=="clear": out.delete("1.0","end")
elif cmd=="time": write(time.strftime("%H:%M:%S"))
elif cmd=="date": write(time.strftime("%Y-%m-%d"))
elif cmd=="system": write(f"{platform.system()} {platform.release()} | Python {platform.python_version()}")
elif cmd=="pwd": write(os.getcwd())
elif cmd=="dir":
try: write("\n".join(os.listdir()))
except Exception as e: write("Error: "+str(e))
elif cmd=="python": write("Python "+platform.python_version())
elif cmd.startswith("echo "): write(cmd[5:])
else: write("Unknown command. Type 'help'.")
out.insert("end","\n> "); out.see("end")
ent.bind("<Return>",run); ent.focus()
def search(self):
win=self.new_window("Search","600x400")
tk.Label(win,text="Search Python OS",font=("Segoe UI",22,"bold")).pack(pady=20)
ent=tk.Entry(win,font=("Segoe UI",13)); ent.pack(fill="x",padx=30)
box=tk.Listbox(win,font=("Segoe UI",11)); box.pack(fill="both",expand=True,padx=30,pady=15)
apps=[("File Explorer",self.explorer),("Notepad",self.notepad),("Calculator",self.calculator),
("Browser",self.browser),("Settings",self.settings),("App Center",self.app_center),("App Manager",self.app_manager),
("Terminal",self.terminal),("Recycle Bin",self.recycle)]
def do(e=None):
q=ent.get().lower(); box.delete(0,"end")
for n,_ in apps:
if q in n.lower(): box.insert("end",n)
def launch(e=None):
s=box.curselection()
if not s:return
for n,c in apps:
if n==box.get(s[0]): c(); break
ent.bind("<KeyRelease>",do); box.bind("<Double-Button-1>",launch)
def recycle(self):
win=self.new_window("Recycle Bin","500x330")
tk.Label(win,text="🗑",font=("Segoe UI Emoji",55)).pack(pady=30)
tk.Label(win,text="Recycle Bin is empty",font=("Segoe UI",13)).pack()
tk.Button(win,text="Close",command=lambda:self.close_window(win)).pack(pady=25)
# ---------- Python OS App System ----------
def installed_apps(self):
result = []
for folder in sorted(os.listdir(self.apps_data)):
p = os.path.join(self.apps_data, folder)
mf = os.path.join(p, "app.json")
if os.path.isdir(p) and os.path.isfile(mf):
try:
with open(mf, encoding="utf-8") as f:
m = json.load(f)
if m.get("id") and m.get("name"):
result.append((p, m))
except Exception:
pass
return result
def app_manager(self):
win = self.new_window("App Manager", "820x560")
tk.Label(win, text="📦 Python OS App Manager",
font=("Segoe UI", 23, "bold")).pack(anchor="w", padx=25, pady=(20, 3))
tk.Label(win, text="Install, launch and uninstall .pyapp applications",
fg="#666").pack(anchor="w", padx=25)
bar = tk.Frame(win); bar.pack(fill="x", padx=20, pady=12)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=20, pady=5)
apps = []
def refresh():
nonlocal apps
apps = self.installed_apps()
box.delete(0, "end")
if not apps:
box.insert("end", " No applications installed")
for folder, m in apps:
box.insert("end", f" {m['name']} — v{m.get('version','1.0')} — {m.get('description','')}")
def selected():
s = box.curselection()
return apps[s[0]] if s and s[0] < len(apps) else None
def launch():
item = selected()
if item:
self.launch_installed_app(*item)
def uninstall():
item = selected()
if not item: return
folder, m = item
if messagebox.askyesno("Uninstall", f"Uninstall {m['name']}?", parent=win):
try:
shutil.rmtree(folder)
refresh()
except Exception as e:
messagebox.showerror("Uninstall", str(e), parent=win)
tk.Button(bar, text="📥 Install .pyapp", command=self.install_app, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="▶ Launch", command=launch, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="🗑 Uninstall", command=uninstall, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="↻ Refresh", command=refresh, relief="flat").pack(side="right", padx=4)
box.bind("<Double-Button-1>", lambda e: launch())
refresh()
def install_app(self):
p = filedialog.askopenfilename(
title="Install Python OS App",
filetypes=[("Python OS App", "*.pyapp"), ("ZIP package", "*.zip"), ("All files", "*.*")])
if not p: return
try:
if not zipfile.is_zipfile(p):
raise ValueError("The selected file is not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id", "name", "version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
messagebox.showinfo("Python OS", f"{manifest['name']} v{manifest['version']} installed successfully!", parent=self.root)
except Exception as e:
messagebox.showerror("Installation failed", str(e), parent=self.root)
def launch_installed_app(self, folder, manifest):
main = os.path.join(folder, "main.py")
if not os.path.isfile(main):
messagebox.showerror("App", "main.py was not found.", parent=self.root)
return
try:
namespace = {"__name__": "__main__", "__file__": main,
"PYTHON_OS_APP": self, "APP_DIR": folder}
with open(main, encoding="utf-8") as f:
source = f.read()
exec(compile(source, main, "exec"), namespace, namespace)
except Exception as e:
messagebox.showerror(f"App error: {manifest.get('name','App')}", str(e), parent=self.root)
def create_example_app(self):
p = filedialog.asksaveasfilename(
title="Create example Python OS App", defaultextension=".pyapp",
filetypes=[("Python OS App", "*.pyapp")], initialfile="HelloPythonOS.pyapp")
if not p: return
manifest = {
"id": "hello-python-os", "name": "Hello Python OS", "version": "1.0",
"description": "A sample Python OS application"
}
main = """import tkinter as tk
win = tk.Toplevel(PYTHON_OS_APP.root)
win.title("Hello Python OS")
win.geometry("430x250")
tk.Label(win, text="🎉 Hello from a Python OS App!",
font=("Segoe UI", 17, "bold")).pack(pady=50)
tk.Label(win, text="This app was installed from a .pyapp package.",
fg="#666").pack()
tk.Button(win, text="Close", command=win.destroy).pack(pady=25)
"""
try:
with zipfile.ZipFile(p, "w", zipfile.ZIP_DEFLATED) as z:
z.writestr("app.json", json.dumps(manifest, indent=2, ensure_ascii=False))
z.writestr("main.py", main)
messagebox.showinfo("Python OS", "Example .pyapp created.", parent=self.root)
except Exception as e:
messagebox.showerror("Create app", str(e), parent=self.root)
def app_store(self):
win = self.new_window("Python OS App Store", "720x470")
tk.Label(win, text="🛍 Python OS App Store",
font=("Segoe UI", 24, "bold")).pack(pady=(25, 5))
tk.Label(win, text="Local application installer",
fg="#666").pack()
tk.Label(win, text="Choose a .pyapp file to install it on Python OS.",
font=("Segoe UI", 11)).pack(pady=25)
tk.Button(win, text="📥 Install .pyapp", command=self.install_app,
width=25, pady=8).pack(pady=6)
tk.Button(win, text="🧪 Create example .pyapp",
command=self.create_example_app, width=25, pady=8).pack(pady=6)
tk.Button(win, text="📦 App Manager",
command=self.app_manager, width=25, pady=8).pack(pady=6)
tk.Label(win, text="Package = ZIP renamed to .pyapp, containing app.json + main.py",
fg="#777", font=("Segoe UI", 9)).pack(pady=25)
# ---------- Microsoft-style App Center ----------
def app_catalog(self):
"""Built-in catalog. A catalog.json can override/extend it."""
built_in = [
{"id":"hello-python-os","name":"Hello Python OS","version":"1.0",
"category":"Demo","description":"A tiny example app for Python OS.",
"type":"builtin"},
{"id":"calculator","name":"Calculator","version":"1.0",
"category":"Tools","description":"Built-in Python OS calculator.",
"type":"builtin"},
{"id":"notepad","name":"Notepad","version":"1.0",
"category":"Productivity","description":"Simple text editor.",
"type":"builtin"},
{"id":"terminal","name":"Terminal","version":"1.0",
"category":"System","description":"Python OS command terminal.",
"type":"builtin"},
]
try:
with open(self.catalog_file, "r", encoding="utf-8") as f:
external = json.load(f)
if isinstance(external, list):
by_id = {x["id"]:x for x in built_in if isinstance(x,dict) and x.get("id")}
for x in external:
if isinstance(x,dict) and x.get("id") and x.get("name"):
by_id[x["id"]] = x
return list(by_id.values())
except Exception:
pass
return built_in
def app_center(self):
win = self.new_window("Microsoft-style App Center", "950x650")
win.minsize(720, 480)
header = tk.Frame(win, bg="#176aa5", height=90)
header.pack(fill="x")
tk.Label(header, text="🛍 Python OS App Center",
bg="#0078d7", fg="white",
font=("Segoe UI", 22, "bold")).pack(side="left", padx=24, pady=22)
search_var = tk.StringVar()
search = tk.Entry(header, textvariable=search_var,
font=("Segoe UI", 11), width=30)
search.pack(side="right", padx=20, pady=27)
search.insert(0, "Search apps...")
body = tk.Frame(win, bg="#f3f3f3")
body.pack(fill="both", expand=True)
categories = tk.Frame(body, bg="#e6e6e6", width=145)
categories.pack(side="left", fill="y")
categories.pack_propagate(False)
content = tk.Frame(body, bg="#f3f3f3")
content.pack(side="left", fill="both", expand=True)
canvas = tk.Canvas(content, bg="#f3f3f3", highlightthickness=0)
scroll = tk.Scrollbar(content, orient="vertical", command=canvas.yview)
cards = tk.Frame(canvas, bg="#f3f3f3")
canvas.create_window((0,0), window=cards, anchor="nw")
canvas.configure(yscrollcommand=scroll.set)
canvas.pack(side="left", fill="both", expand=True)
scroll.pack(side="right", fill="y")
catalog = self.app_catalog()
current_category = ["All"]
def installed_ids():
return {m.get("id") for _, m in self.installed_apps()}
def launch_builtin(app_id):
mapping = {
"calculator": self.calculator,
"notepad": self.notepad,
"terminal": self.terminal,
"hello-python-os": self.create_example_app,
}
if app_id in mapping:
mapping[app_id]()
def install_catalog_item(app):
if app.get("type") == "builtin":
if app["id"] in installed_ids():
launch_builtin(app["id"])
return
# Built-ins are represented by creating a real .pyapp package.
if app["id"] == "hello-python-os":
self.create_example_app()
return
messagebox.showinfo(
"Python OS", "This built-in app is already part of Python OS.",
parent=win)
return
url = app.get("url")
if not url:
messagebox.showwarning(
"Python OS", "This catalog entry has no download URL.", parent=win)
return
self.download_and_install(url, app.get("name","App"), win)
def render():
for w in cards.winfo_children():
w.destroy()
q = search_var.get().lower().strip()
installed = installed_ids()
shown = 0
for app in catalog:
cat = app.get("category","Other")
if current_category[0] != "All" and cat != current_category[0]:
continue
if q and q not in (app.get("name","")+" "+app.get("description","")).lower():
continue
card = tk.Frame(cards, bg="white", bd=1, relief="solid",
padx=14, pady=10)
card.pack(fill="x", padx=18, pady=8)
shown += 1
icon = app.get("icon","📦")
tk.Label(card, text=icon, bg="white",
font=("Segoe UI Emoji", 30)).pack(side="left", padx=8)
info = tk.Frame(card, bg="white")
info.pack(side="left", fill="x", expand=True)
tk.Label(info, text=app.get("name","Unnamed"),
bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack(anchor="w")
tk.Label(info, text=f"v{app.get('version','1.0')} • {cat}",
bg="white", fg="#777").pack(anchor="w")
tk.Label(info, text=app.get("description",""),
bg="white", fg="#555", wraplength=470,
justify="left").pack(anchor="w", pady=(4,0))
aid = app.get("id")
if aid in installed:
button_text = "▶ Open"
elif app.get("type") == "builtin" and aid != "hello-python-os":
button_text = "Included"
else:
button_text = "📥 Install"
tk.Button(card, text=button_text,
command=lambda a=app: install_catalog_item(a),
width=12, relief="flat",
bg="#0878c9" if button_text != "Included" else "#ddd",
fg="white" if button_text != "Included" else "#555").pack(
side="right", padx=10)
if shown == 0:
tk.Label(cards, text="No apps found.",
bg="#f3f3f3", fg="#777",
font=("Segoe UI", 12)).pack(pady=40)
cards.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
cats = ["All"] + sorted({a.get("category","Other") for a in catalog})
for cat in cats:
tk.Button(categories, text=cat, command=lambda c=cat:(
current_category.__setitem__(0,c), render()),
anchor="w", relief="flat", bg="#e6e6e6",
font=("Segoe UI", 10)).pack(fill="x", padx=8, pady=3)
search_var.trace_add("write", lambda *args: render())
footer = tk.Frame(win, bg="#202020", height=45)
footer.pack(fill="x")
tk.Button(footer, text="📦 App Manager", command=self.app_manager,
relief="flat").pack(side="left", padx=10, pady=8)
tk.Label(footer, text="Python OS 9.0 • Windows 10 Edition",
bg="#202020", fg="white").pack(side="right", padx=15)
render()
def download_and_install(self, url, app_name, parent):
"""Download a .pyapp URL and pass it through the normal installer."""
def worker():
temp_path = os.path.join(
self.apps_dir, "download_" + next(tempfile._get_candidate_names()) + ".pyapp")
try:
urllib.request.urlretrieve(url, temp_path)
# Reuse installation logic by directly installing this downloaded file.
self.install_app_file(temp_path, parent)
except Exception as e:
self.root.after(0, lambda: messagebox.showerror(
"Download failed", f"{app_name}\n\n{e}", parent=parent))
finally:
try:
if os.path.exists(temp_path):
os.remove(temp_path)
except Exception:
pass
threading.Thread(target=worker, daemon=True).start()
messagebox.showinfo(
"Python OS", f"Downloading {app_name} in the background...",
parent=parent)
def install_app_file(self, p, parent=None):
try:
if not zipfile.is_zipfile(p):
raise ValueError("Not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id","name","version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
target = parent or self.root
self.root.after(0, lambda: messagebox.showinfo(
"Python OS", f"{manifest['name']} v{manifest['version']} installed!",
parent=target))
except Exception as e:
target = parent or self.root
self.root.after(0, lambda: messagebox.showerror(
"Installation failed", str(e), parent=target))
# ---------- context / shutdown ----------
# ---------- Python OS 9.0 Windows-10 style features ----------
def show_desktop(self):
for w, _ in list(self.tasks):
try:
if w.winfo_exists():
w.withdraw()
except Exception:
pass
def minimize_all(self):
self.show_desktop()
def open_run(self):
win = self.new_window("Run", "500x190")
tk.Label(win, text="Run", font=("Segoe UI", 18, "bold")).pack(anchor="w", padx=20, pady=(18, 5))
tk.Label(win, text="Type the name of a program or Python OS command.").pack(anchor="w", padx=20)
ent = tk.Entry(win, font=("Segoe UI", 11))
ent.pack(fill="x", padx=20, pady=12)
def go(e=None):
q = ent.get().strip()
if not q:
return
commands = {
"explorer": self.explorer, "notepad": self.notepad,
"calc": self.calculator, "calculator": self.calculator,
"terminal": self.terminal, "cmd": self.terminal,
"settings": self.settings, "store": self.app_center,
"app center": self.app_center
}
if q.lower() in commands:
commands[q.lower()]()
self.close_window(win)
else:
try:
if platform.system() == "Windows":
subprocess.Popen(q, shell=True)
else:
subprocess.Popen(q, shell=True)
self.close_window(win)
except Exception as ex:
messagebox.showerror("Run", str(ex), parent=win)
tk.Button(win, text="OK", command=go, width=10).pack(side="right", padx=10)
tk.Button(win, text="Cancel", command=lambda:self.close_window(win), width=10).pack(side="right")
ent.bind("<Return>", go)
ent.focus_force()
def alt_tab(self, event=None):
live=[]
for w, _ in list(self.tasks):
try:
if w.winfo_exists() and w.state() != "withdrawn":
live.append(w)
except Exception:
pass
if not live:
return "break"
self.alt_tab_index=(self.alt_tab_index+1) % len(live)
self.focus(live[self.alt_tab_index])
return "break"
def power_menu_open(self):
if self.power_menu and self.power_menu.winfo_exists():
self.power_menu.destroy(); self.power_menu=None; return
m=tk.Toplevel(self.root)
self.power_menu=m
m.overrideredirect(True)
m.configure(bg="#f4f4f4", bd=1, relief="solid")
w=290; h=270
x=self.root.winfo_rootx()+self.root.winfo_width()-w-12
y=self.root.winfo_rooty()+self.root.winfo_height()-h-62
m.geometry(f"{w}x{h}+{max(0,x)}+{max(0,y)}")
tk.Label(m,text="Power",bg="#f4f4f4",fg="#222",font=("Segoe UI",17,"bold")).pack(anchor="w",padx=18,pady=(16,8))
tk.Label(m,text="What do you want to do?",bg="#f4f4f4",fg="#666").pack(anchor="w",padx=18,pady=(0,10))
def act(fn):
if m.winfo_exists(): m.destroy()
self.power_menu=None
fn()
for text,fn in [("⏾ Sleep",self.sleep_os),("↻ Restart",self.restart_os),("🔒 Lock",self.lock_screen),("⏻ Shut down",self.shutdown)]:
tk.Button(m,text=text,command=lambda f=fn:act(f),anchor="w",bg="white",fg="#222",
activebackground="#dceefa",relief="flat",font=("Segoe UI",11),height=2).pack(fill="x",padx=12,pady=2)
m.bind("<Escape>",lambda e:m.destroy())
m.focus_force()
def sleep_os(self):
self.show_desktop()
self.notify("Power", "Python OS is in sleep mode.")
def restart_os(self):
self.close_start()
self.clear()
self.windows=[]; self.tasks=[]
self.boot()
def taskbar_menu(self, event):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="Toolbars")
m.add_separator()
m.add_command(label="Task Manager", command=self.task_manager)
m.add_command(label="Show the desktop", command=self.show_desktop)
m.add_separator()
m.add_command(label="Taskbar settings", command=self.settings)
m.tk_popup(event.x_root, event.y_root)
def task_manager(self):
win = self.new_window("Task Manager", "650x430")
tk.Label(win, text="Task Manager", font=("Segoe UI", 22, "bold")).pack(anchor="w", padx=20, pady=18)
box = tk.Listbox(win, font=("Consolas", 10))
box.pack(fill="both", expand=True, padx=20, pady=5)
def refresh():
box.delete(0, "end")
box.insert("end", "Python OS processes")
box.insert("end", "-" * 55)
for w, b in self.tasks:
try:
if w.winfo_exists():
box.insert("end", f"APP {w.title()}")
except Exception:
pass
box.insert("end", "")
box.insert("end", f"Open windows: {len(self.tasks)}")
box.insert("end", f"Python: {platform.python_version()}")
tk.Button(win, text="↻ Refresh", command=refresh).pack(anchor="e", padx=20, pady=8)
refresh()
def context(self, e):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="View")
m.add_command(label="Sort by")
m.add_separator()
m.add_command(label="Refresh", command=lambda:self.desktop_frame.update())
m.add_separator()
m.add_command(label="Open File Explorer", command=self.explorer)
m.add_command(label="Open Terminal", command=self.terminal)
m.add_command(label="Personalize", command=self.personalize)
m.add_command(label="About Python OS", command=self.system_info)
m.add_separator()
m.add_command(label="Show desktop", command=self.show_desktop)
m.add_command(label="Shut Down", command=self.shutdown)
m.tk_popup(e.x_root, e.y_root)
def shutdown(self):
if messagebox.askyesno("Python OS","Shut down Python OS?",parent=self.root):
self.root.configure(bg="#080808")
for w in self.root.winfo_children():
w.destroy()
tk.Label(self.root,text="⏻",fg="white",bg="#080808",font=("Segoe UI",70)).pack(pady=(220,10))
tk.Label(self.root,text="Python OS is shutting down...",fg="white",bg="#080808",font=("Segoe UI",16)).pack()
self.root.after(900,self.root.destroy)
if __name__=="__main__":
root=tk.Tk()
PythonOS(root)
root.mainloop()
elif x == 2 :
import tkinter as tk
from tkinter import messagebox, filedialog, colorchooser, ttk
import os, time, platform, subprocess, json, math, zipfile, shutil, tempfile, re, urllib.request, threading
class PythonOS:
def __init__(self, root):
self.root = root
self.root.title("Python OS 10.0")
self.root.geometry("1366x768")
self.root.minsize(1050, 650)
self.wallpaper = "#0078d7"
self.username = "User"
self.notifications = []
self.wallpaper_image = None
self.windows = []
self.tasks = []
self.start_open = False
self.menu = None
self.power_menu = None
self.desktop_icons = []
self.alt_tab_index = 0
self.virtual_desktop = 1
self.desktop_count = 3
self.window_desktops = {}
self.wallpaper_path = ""
self.volume = 70
self.brightness = 80
self.settings_file = os.path.join(os.path.expanduser("~"), ".python_os_settings.json")
self.apps_dir = os.path.join(os.path.expanduser("~"), ".python_os_apps")
self.apps_data = os.path.join(self.apps_dir, "installed")
self.catalog_file = os.path.join(self.apps_dir, "catalog.json")
os.makedirs(self.apps_data, exist_ok=True)
self.load_settings()
if self.wallpaper_path and os.path.isfile(self.wallpaper_path):
try: self.wallpaper_image=tk.PhotoImage(file=self.wallpaper_path)
except Exception: self.wallpaper_image=None
self.boot()
# ---------- startup ----------
def load_settings(self):
try:
with open(self.settings_file, "r", encoding="utf-8") as f:
d = json.load(f)
self.wallpaper = d.get("wallpaper", self.wallpaper)
self.username = d.get("username", "User")
self.wallpaper_path = d.get("wallpaper_path", "")
self.volume = int(d.get("volume", 70))
self.brightness = int(d.get("brightness", 80))
except Exception:
pass
def save_settings(self):
try:
with open(self.settings_file, "w", encoding="utf-8") as f:
json.dump({"wallpaper": self.wallpaper, "username": self.username, "wallpaper_path": self.wallpaper_path, "volume": self.volume, "brightness": self.brightness}, f)
except Exception:
pass
def boot(self):
self.clear()
self.root.configure(bg="#080808")
box = tk.Frame(self.root, bg="#080808")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#080808",
font=("Segoe UI", 80)).pack(pady=(150, 0))
tk.Label(box, text="Python OS", fg="white", bg="#080808",
font=("Segoe UI", 28, "bold")).pack()
tk.Label(box, text="Loading desktop...", fg="#aaa", bg="#080808",
font=("Segoe UI", 10)).pack(pady=12)
bar = tk.Frame(box, bg="#333", width=300, height=5)
bar.pack()
bar.pack_propagate(False)
fill = tk.Frame(bar, bg="#1683d8", width=0, height=5)
fill.pack(side="left")
def animate(n=0):
if n <= 300 and box.winfo_exists():
fill.config(width=n)
self.root.after(7, lambda: animate(n + 4))
animate()
self.root.after(1500, self.login)
def login(self):
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 65)).pack(pady=(115, 0))
tk.Label(box, text="Python OS", fg="white", bg="#176aa5",
font=("Segoe UI", 27, "bold")).pack()
card = tk.Frame(box, bg="white", width=350, height=190)
card.pack(pady=22)
card.pack_propagate(False)
tk.Label(card, text="👤", bg="white", font=("Segoe UI Emoji", 30)).pack(pady=12)
tk.Label(card, text=self.username, bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack()
b = tk.Button(card, text="Sign in", command=self.desktop,
bg="#0878c9", fg="white", relief="flat",
font=("Segoe UI", 11, "bold"), padx=38, pady=7)
b.pack(pady=12)
self.root.bind("<Return>", lambda e: self.desktop())
def clear(self):
for w in self.root.winfo_children():
w.destroy()
# ---------- desktop ----------
def desktop(self):
self.root.unbind("<Return>")
self.clear()
self.root.bind_all("<Control-Alt-d>", lambda e: self.show_desktop())
self.root.bind_all("<Control-Alt-r>", lambda e: self.open_run())
self.root.bind_all("<Control-Alt-t>", lambda e: self.terminal())
self.root.bind_all("<Control-Alt-l>", lambda e: self.lock_screen())
self.root.bind_all("<Alt-KeyPress-Tab>", self.alt_tab)
self.root.bind_all("<Control-Alt-s>", lambda e: self.power_menu_open())
self.root.bind_all("<Control-Alt-v>", lambda e: self.virtual_desktops())
self.root.bind_all("<Control-Alt-p>", lambda e: self.paint())
self.root.bind_all("<Control-Alt-c>", lambda e: self.calendar_app())
self.root.configure(bg=self.wallpaper)
self.desktop_frame = tk.Frame(self.root, bg=self.wallpaper)
self.desktop_frame.pack(fill="both", expand=True)
if self.wallpaper_image:
self._wall_img_label = tk.Label(self.desktop_frame, image=self.wallpaper_image, bd=0)
self._wall_img_label.place(relx=0, rely=0, relwidth=1, relheight=1)
self._wall_img_label.lower()
# wallpaper branding
tk.Label(self.desktop_frame, text="Python OS",
bg=self.wallpaper, fg="white",
font=("Segoe UI", 40, "bold")).place(relx=.5, rely=.40, anchor="center")
tk.Label(self.desktop_frame, text="Version 10.0",
bg=self.wallpaper, fg="#d9efff",
font=("Segoe UI", 11)).place(relx=.5, rely=.48, anchor="center")
icons = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("⚙", "Settings", self.settings),
("💻", "Terminal", self.terminal),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
for i, item in enumerate(icons):
x = 22 + (i // 6) * 105
y = 20 + (i % 6) * 92
self.icon(*item, x=x, y=y)
# taskbar
self.taskbar = tk.Frame(self.root, bg="#1f1f1f", height=48)
self.taskbar.pack(side="bottom", fill="x")
self.taskbar.pack_propagate(False)
tk.Button(self.taskbar, text="⊞", command=self.toggle_start,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 23)).pack(side="left", padx=6)
tk.Button(self.taskbar, text="🔍", command=self.search,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 13)).pack(side="left", padx=3)
self.task_area = tk.Frame(self.taskbar, bg="#1f1f1f")
self.task_area.pack(side="left", fill="both", expand=True, padx=8)
# Windows 10 style pinned taskbar buttons
for text, cmd in [("▣", self.explorer), ("🌐", self.browser), ("🛍", self.app_center)]:
tk.Button(self.taskbar, text=text, command=cmd, bg="#1f1f1f", fg="white",
activebackground="#333333", relief="flat", bd=0,
font=("Segoe UI Emoji", 13)).pack(side="left", padx=2)
tray = tk.Frame(self.taskbar, bg="#202020")
tray.pack(side="right", fill="y")
tk.Button(tray, text="🔔", command=self.notification_center, bg="#202020", fg="white", relief="flat", bd=0).pack(side="left", padx=3)
tk.Button(tray, text="⌁ 🔊", command=self.quick_controls, bg="#202020", fg="white", relief="flat", bd=0,
font=("Segoe UI", 11)).pack(side="left", padx=4)
tk.Button(tray, text="⏻", command=self.power_menu_open, bg="#202020", fg="white",
activebackground="#3b3b3b", relief="flat", bd=0, font=("Segoe UI", 14)).pack(side="left", padx=4)
self.clock = tk.Label(tray, bg="#202020", fg="white",
font=("Segoe UI", 9), justify="right")
self.clock.pack(side="left", padx=10)
self.tick()
self.desktop_frame.bind("<Button-3>", self.context)
self.desktop_frame.bind("<Double-Button-1>", lambda e: self.close_start())
def icon(self, emoji, name, command, x, y):
f = tk.Frame(self.desktop_frame, bg=self.wallpaper, width=92, height=82)
f.place(x=x, y=y)
f.pack_propagate(False)
btn = tk.Button(f, text=emoji, command=command,
bg=self.wallpaper, fg="white", activebackground="#2b89c9",
relief="flat", bd=0, font=("Segoe UI Emoji", 25))
btn.pack(fill="x")
tk.Label(f, text=name, bg=self.wallpaper, fg="white",
font=("Segoe UI", 9), wraplength=88).pack()
self.desktop_icons.append(f)
def start_drag(e):
f._dx, f._dy = e.x, e.y
def drag(e):
nx=max(4, min(self.root.winfo_width()-100, f.winfo_x()+e.x-f._dx))
ny=max(4, min(self.root.winfo_height()-145, f.winfo_y()+e.y-f._dy))
f.place(x=nx, y=ny)
for w in (f, btn):
w.bind("<ButtonPress-1>", start_drag, add="+")
w.bind("<B1-Motion>", drag, add="+")
def quick_controls(self):
win=self.new_window("Quick Settings", "430x300")
tk.Label(win,text="⚡ Quick settings",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=20,pady=18)
for text,cmd in [("🎨 Personalization",self.personalize),("🔔 Notifications",self.notification_center),("⚙ Settings",self.settings),("ℹ About",self.system_info)]:
tk.Button(win,text=text,command=cmd,anchor="w",relief="flat",font=("Segoe UI",11)).pack(fill="x",padx=20,pady=4)
def tick(self):
if hasattr(self, "clock") and self.clock.winfo_exists():
self.clock.config(text=time.strftime("%H:%M\n%d/%m/%Y"))
self.root.after(1000, self.tick)
# ---------- Python OS 10.0 system features ----------
def notify(self, title, text):
self.notifications.append((title, text, time.strftime("%H:%M")))
if len(self.notifications) > 30:
self.notifications = self.notifications[-30:]
def notification_center(self):
win = self.new_window("Notification Center", "520x520")
win.configure(bg="#f4f4f4")
tk.Label(win, text="🔔 Notifications", bg="#f4f4f4", fg="#222",
font=("Segoe UI", 20, "bold")).pack(anchor="w", padx=20, pady=18)
body = tk.Frame(win, bg="#f4f4f4")
body.pack(fill="both", expand=True, padx=14)
if not self.notifications:
tk.Label(body, text="You're all caught up.", bg="#f4f4f4", fg="#777",
font=("Segoe UI", 12)).pack(pady=50)
else:
for title, text, stamp in reversed(self.notifications):
card = tk.Frame(body, bg="white", bd=1, relief="solid")
card.pack(fill="x", pady=5)
tk.Label(card, text=f"{title} • {stamp}", bg="white", fg="#222",
font=("Segoe UI", 11, "bold")).pack(anchor="w", padx=12, pady=(9,2))
tk.Label(card, text=text, bg="white", fg="#555", wraplength=450,
justify="left").pack(anchor="w", padx=12, pady=(0,9))
tk.Button(win, text="Clear notifications", command=lambda:self.clear_notifications(win),
relief="flat").pack(anchor="e", padx=18, pady=12)
def clear_notifications(self, win=None):
self.notifications.clear()
if win and win.winfo_exists():
self.close_window(win)
self.notification_center()
def lock_screen(self):
self.close_start()
for w, _ in list(self.tasks):
try:
if w.winfo_exists(): w.withdraw()
except Exception: pass
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 80)).pack(pady=(125, 0))
tk.Label(box, text=self.username, fg="white", bg="#176aa5",
font=("Segoe UI", 24, "bold")).pack(pady=8)
tk.Label(box, text=time.strftime("%A, %d %B\n%H:%M"), fg="white", bg="#176aa5",
font=("Segoe UI", 18)).pack(pady=10)
b=tk.Button(box, text="🔓 Sign in", command=self.unlock_screen,
font=("Segoe UI", 12, "bold"), padx=30, pady=10)
b.pack(pady=25)
self.root.bind("<Return>", lambda e: self.unlock_screen())
def unlock_screen(self):
self.root.unbind("<Return>")
self.desktop()
self.notify("Python OS", "You signed in successfully.")
def personalize(self):
win=self.new_window("Personalization", "620x470")
tk.Label(win,text="🎨 Personalization",font=("Segoe UI",22,"bold")).pack(anchor="w",padx=20,pady=18)
tk.Label(win,text="Choose your desktop appearance.",fg="#666").pack(anchor="w",padx=20)
row=tk.Frame(win); row.pack(fill="x",padx=20,pady=20)
tk.Button(row,text="Choose color",command=self.choose_wallpaper).pack(side="left",padx=5)
tk.Button(row,text="Choose wallpaper image",command=self.choose_wallpaper_image).pack(side="left",padx=5)
tk.Button(row,text="Reset",command=lambda:self.reset_wallpaper()).pack(side="left",padx=5)
tk.Label(win,text="Keyboard shortcuts",font=("Segoe UI",14,"bold")).pack(anchor="w",padx=20,pady=(15,5))
tk.Label(win,text="Ctrl+Alt+D Show desktop\nCtrl+Alt+R Run\nCtrl+Alt+T Terminal\nCtrl+Alt+L Lock screen",justify="left").pack(anchor="w",padx=20)
def choose_wallpaper(self):
c=colorchooser.askcolor(title="Choose desktop color")
if c and c[1]:
self.wallpaper=c[1]
self.wallpaper_image=None
self.save_settings()
self.desktop()
self.notify("Personalization", "Desktop color changed.")
def choose_wallpaper_image(self):
path=filedialog.askopenfilename(title="Choose wallpaper",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if path:
try:
self.wallpaper_image=tk.PhotoImage(file=path)
self.wallpaper_path=path
self.wallpaper="#000000"
self.save_settings()
self.desktop()
self.notify("Personalization", "Wallpaper image applied.")
except Exception as e:
messagebox.showerror("Wallpaper", f"Could not load image.\n{e}")
def reset_wallpaper(self):
self.wallpaper="#0078d7"
self.wallpaper_image=None
self.wallpaper_path=""
self.save_settings(); self.desktop()
def system_info(self):
win=self.new_window("About Python OS", "560x390")
tk.Label(win,text="⊞ Python OS 10.0",font=("Segoe UI",24,"bold")).pack(pady=25)
info=f"Windows 10 Edition\n\nPython: {platform.python_version()}\nPlatform: {platform.platform()}\nArchitecture: {platform.machine()}\nUser: {self.username}"
tk.Label(win,text=info,justify="left",font=("Segoe UI",11)).pack(anchor="w",padx=35)
# ---------- windows ----------
def new_window(self, title, size="700x480"):
self.close_start()
win = tk.Toplevel(self.root)
win.title(title)
win.geometry(size)
win.minsize(350, 230)
win.protocol("WM_DELETE_WINDOW", lambda: self.close_window(win))
win.bind("<FocusIn>", lambda e: self.focus(win))
self.windows.append(win)
b = tk.Button(self.task_area, text=title[:18], command=lambda: self.focus(win),
bg="#303030", fg="white", activebackground="#505050",
relief="flat", bd=0, font=("Segoe UI", 9), padx=9)
b.pack(side="left", padx=2, pady=6)
self.tasks.append((win, b))
if hasattr(self, "window_desktops"):
self._window_shortcuts(win)
win.focus_force()
return win
def focus(self, win):
if win.winfo_exists():
win.deiconify()
win.lift()
win.focus_force()
def close_window(self, win):
for w, b in list(self.tasks):
if w is win:
b.destroy()
self.tasks.remove((w, b))
if win in self.windows:
self.windows.remove(win)
if win.winfo_exists():
win.destroy()
# ---------- start ----------
def toggle_start(self):
if self.start_open:
self.close_start()
return
self.start_open = True
self.start = tk.Frame(self.root, bg="#f4f4f4", width=620, height=620,
bd=1, relief="solid")
self.start.place(x=6, y=max(5, self.root.winfo_height()-665))
self.start.lift()
head = tk.Frame(self.start, bg="#0078d7", height=76)
head.pack(fill="x")
tk.Label(head, text=f"👤 {self.username}", bg="#0078d7", fg="white",
font=("Segoe UI", 14, "bold")).pack(side="left", padx=20, pady=22)
search = tk.Entry(self.start, font=("Segoe UI", 11))
search.pack(fill="x", padx=16, pady=12)
search.insert(0, "Search apps...")
search.bind("<FocusIn>", lambda e: search.delete(0, "end") if search.get()=="Search apps..." else None)
body = tk.Frame(self.start, bg="#f4f4f4")
body.pack(fill="both", expand=True)
apps = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("💻", "Terminal", self.terminal),
("⚙", "Settings", self.settings),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
buttons = []
for ico, name, cmd in apps:
b = tk.Button(body, text=f"{ico} {name}", command=cmd,
anchor="w", bg="#f4f4f4", fg="#222",
activebackground="#dceefa", relief="flat",
font=("Segoe UI", 11), height=2)
b.pack(fill="x", padx=12, pady=1)
buttons.append((name.lower(), b))
def filter_apps(e=None):
q = search.get().lower()
for n, b in buttons:
b.pack_forget()
if q in n:
b.pack(fill="x", padx=12, pady=1)
search.bind("<KeyRelease>", filter_apps)
bottom = tk.Frame(self.start, bg="#e7e7e7", height=48)
bottom.pack(side="bottom", fill="x")
tk.Button(bottom, text="⚙ Settings", command=self.settings,
bg="#e7e7e7", relief="flat").pack(side="left", padx=12, pady=9)
tk.Button(bottom, text="🔒 Lock", command=self.lock_screen,
bg="#e7e7e7", relief="flat").pack(side="right", padx=4, pady=9)
tk.Button(bottom, text="⏻ Shut down", command=self.shutdown,
bg="#e7e7e7", relief="flat").pack(side="right", padx=12, pady=9)
def close_start(self):
if self.start_open and self.start.winfo_exists():
self.start.destroy()
self.start_open = False
# ---------- apps ----------
def explorer(self):
win = self.new_window("File Explorer", "900x560")
toolbar = tk.Frame(win, bg="#eeeeee")
toolbar.pack(fill="x")
path = tk.StringVar(value=os.path.expanduser("~"))
ent = tk.Entry(toolbar, textvariable=path, font=("Segoe UI", 10))
ent.pack(side="left", fill="x", expand=True, padx=6, pady=6)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=6, pady=6)
def load(p):
try:
p = os.path.abspath(os.path.expanduser(p))
items = sorted(os.listdir(p), key=lambda x:(not os.path.isdir(os.path.join(p,x)), x.lower()))
box.delete(0, "end")
for i in items:
box.insert("end", ("📁 " if os.path.isdir(os.path.join(p,i)) else "📄 ")+i)
path.set(p)
except Exception as e:
messagebox.showerror("File Explorer", str(e), parent=win)
def open_item(e=None):
s = box.curselection()
if not s: return
name = box.get(s[0])[2:]
p = os.path.join(path.get(), name)
if os.path.isdir(p):
load(p)
else:
try:
if platform.system()=="Windows": os.startfile(p)
elif platform.system()=="Darwin": subprocess.Popen(["open",p])
else: subprocess.Popen(["xdg-open",p])
except Exception as e:
messagebox.showerror("Open", str(e), parent=win)
tk.Button(toolbar, text="↑", command=lambda:load(os.path.dirname(path.get()))).pack(side="left")
tk.Button(toolbar, text="Go", command=lambda:load(path.get())).pack(side="right", padx=5)
ent.bind("<Return>", lambda e:load(path.get()))
box.bind("<Double-Button-1>", open_item)
load(path.get())
def notepad(self):
win = self.new_window("Notepad", "800x560")
bar = tk.Frame(win, bg="#eeeeee"); bar.pack(fill="x")
text = tk.Text(win, font=("Consolas", 12), undo=True, wrap="word")
text.pack(fill="both", expand=True)
def new(): text.delete("1.0","end")
def openf():
p=filedialog.askopenfilename(parent=win,filetypes=[("Text","*.txt"),("All","*.*")])
if p:
try:
text.delete("1.0","end"); text.insert("1.0",open(p,encoding="utf-8").read())
except Exception as e: messagebox.showerror("Notepad",str(e),parent=win)
def save():
p=filedialog.asksaveasfilename(parent=win,defaultextension=".txt",
filetypes=[("Text","*.txt"),("All","*.*")])
if p: open(p,"w",encoding="utf-8").write(text.get("1.0","end-1c"))
for n,c in [("New",new),("Open",openf),("Save",save)]:
tk.Button(bar,text=n,command=c,relief="flat").pack(side="left",padx=4,pady=4)
def calculator(self):
win=self.new_window("Calculator","380x520")
exp=tk.StringVar()
tk.Entry(win,textvariable=exp,justify="right",font=("Segoe UI",24),bd=0).pack(fill="x",padx=12,pady=15,ipady=8)
grid=tk.Frame(win); grid.pack(fill="both",expand=True,padx=8,pady=8)
keys=[["C","(",")","/"],["7","8","9","*"],["4","5","6","-"],["1","2","3","+"],["0",".","⌫","="]]
def press(k):
if k=="C": exp.set("")
elif k=="⌫": exp.set(exp.get()[:-1])
elif k=="=":
try:
if any(c not in "0123456789.+-*/() " for c in exp.get()): raise ValueError()
exp.set(str(eval(exp.get(),{"__builtins__":{}},{})))
except: exp.set("Error")
else: exp.set(exp.get()+k)
for r,row in enumerate(keys):
for c,k in enumerate(row):
tk.Button(grid,text=k,command=lambda x=k:press(x),
font=("Segoe UI",13),relief="flat").grid(row=r,column=c,sticky="nsew",padx=2,pady=2)
for r in range(5): grid.rowconfigure(r,weight=1)
for c in range(4): grid.columnconfigure(c,weight=1)
def browser(self):
win=self.new_window("Python Browser","760x520")
tk.Label(win,text="🌐 Python Browser",font=("Segoe UI",20,"bold")).pack(pady=18)
tk.Label(win,text="This lightweight browser opens web pages in your default browser.",
fg="#666").pack()
url=tk.Entry(win,font=("Segoe UI",12))
url.pack(fill="x",padx=35,pady=15)
url.insert(0,"https://[Log in to view URL]")
def go():
u=url.get().strip()
if not u.startswith(("http://","https://")): u="https://"+u
try:
import webbrowser; webbrowser.open(u)
except Exception as e: messagebox.showerror("Browser",str(e),parent=win)
tk.Button(win,text="Open website",command=go,width=18).pack()
def settings(self):
win=self.new_window("Settings","700x520")
tk.Label(win,text="Settings",font=("Segoe UI",26,"bold")).pack(anchor="w",padx=25,pady=20)
tk.Label(win,text="Personalization",font=("Segoe UI",13,"bold")).pack(anchor="w",padx=25,pady=5)
colors=[("Windows Blue","#0878c9"),("Dark Blue","#123b63"),("Green","#197a3a"),
("Purple","#663399"),("Dark","#222222")]
def setbg(c):
self.wallpaper=c
self.desktop_frame.config(bg=c)
for w in self.desktop_frame.winfo_children():
try: w.config(bg=c)
except: pass
self.save_settings()
for n,c in colors:
tk.Button(win,text=n,command=lambda c=c:setbg(c),width=24,anchor="w").pack(anchor="w",padx=25,pady=3)
tk.Button(win,text="Choose custom color",
command=lambda:(lambda c:c and setbg(c))(colorchooser.askcolor(parent=win)[1])).pack(anchor="w",padx=25,pady=8)
tk.Label(win,text=f"Python {platform.python_version()} • {platform.system()}",
fg="#777").pack(anchor="w",padx=25,pady=18)
def terminal(self):
win=self.new_window("Terminal","800x500")
out=tk.Text(win,bg="#0c0c0c",fg="#eee",insertbackground="white",font=("Consolas",11))
out.pack(fill="both",expand=True)
out.insert("end","Python OS Terminal 3.0\nType 'help' for commands.\n\n> ")
ent=tk.Entry(win,bg="#0c0c0c",fg="white",insertbackground="white",font=("Consolas",11))
ent.pack(fill="x")
def write(s): out.insert("end",s+"\n"); out.see("end")
def run(e=None):
cmd=ent.get().strip(); ent.delete(0,"end")
if not cmd:return
out.insert("end",cmd+"\n")
if cmd=="help": write("help, clear, time, date, system, pwd, dir, echo <text>, python")
elif cmd=="clear": out.delete("1.0","end")
elif cmd=="time": write(time.strftime("%H:%M:%S"))
elif cmd=="date": write(time.strftime("%Y-%m-%d"))
elif cmd=="system": write(f"{platform.system()} {platform.release()} | Python {platform.python_version()}")
elif cmd=="pwd": write(os.getcwd())
elif cmd=="dir":
try: write("\n".join(os.listdir()))
except Exception as e: write("Error: "+str(e))
elif cmd=="python": write("Python "+platform.python_version())
elif cmd.startswith("echo "): write(cmd[5:])
else: write("Unknown command. Type 'help'.")
out.insert("end","\n> "); out.see("end")
ent.bind("<Return>",run); ent.focus()
def search(self):
win=self.new_window("Search","600x400")
tk.Label(win,text="Search Python OS",font=("Segoe UI",22,"bold")).pack(pady=20)
ent=tk.Entry(win,font=("Segoe UI",13)); ent.pack(fill="x",padx=30)
box=tk.Listbox(win,font=("Segoe UI",11)); box.pack(fill="both",expand=True,padx=30,pady=15)
apps=[("File Explorer",self.explorer),("Notepad",self.notepad),("Calculator",self.calculator),
("Browser",self.browser),("Settings",self.settings),("App Center",self.app_center),("App Manager",self.app_manager),
("Terminal",self.terminal),("Recycle Bin",self.recycle),("Paint",self.paint),("Calendar",self.calendar_app),("System Monitor",self.system_monitor),("Image Viewer",self.image_viewer)]
def do(e=None):
q=ent.get().lower(); box.delete(0,"end")
for n,_ in apps:
if q in n.lower(): box.insert("end",n)
def launch(e=None):
s=box.curselection()
if not s:return
for n,c in apps:
if n==box.get(s[0]): c(); break
ent.bind("<KeyRelease>",do); box.bind("<Double-Button-1>",launch)
def recycle(self):
win=self.new_window("Recycle Bin","500x330")
tk.Label(win,text="🗑",font=("Segoe UI Emoji",55)).pack(pady=30)
tk.Label(win,text="Recycle Bin is empty",font=("Segoe UI",13)).pack()
tk.Button(win,text="Close",command=lambda:self.close_window(win)).pack(pady=25)
# ---------- Python OS App System ----------
def installed_apps(self):
result = []
for folder in sorted(os.listdir(self.apps_data)):
p = os.path.join(self.apps_data, folder)
mf = os.path.join(p, "app.json")
if os.path.isdir(p) and os.path.isfile(mf):
try:
with open(mf, encoding="utf-8") as f:
m = json.load(f)
if m.get("id") and m.get("name"):
result.append((p, m))
except Exception:
pass
return result
def app_manager(self):
win = self.new_window("App Manager", "820x560")
tk.Label(win, text="📦 Python OS App Manager",
font=("Segoe UI", 23, "bold")).pack(anchor="w", padx=25, pady=(20, 3))
tk.Label(win, text="Install, launch and uninstall .pyapp applications",
fg="#666").pack(anchor="w", padx=25)
bar = tk.Frame(win); bar.pack(fill="x", padx=20, pady=12)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=20, pady=5)
apps = []
def refresh():
nonlocal apps
apps = self.installed_apps()
box.delete(0, "end")
if not apps:
box.insert("end", " No applications installed")
for folder, m in apps:
box.insert("end", f" {m['name']} — v{m.get('version','1.0')} — {m.get('description','')}")
def selected():
s = box.curselection()
return apps[s[0]] if s and s[0] < len(apps) else None
def launch():
item = selected()
if item:
self.launch_installed_app(*item)
def uninstall():
item = selected()
if not item: return
folder, m = item
if messagebox.askyesno("Uninstall", f"Uninstall {m['name']}?", parent=win):
try:
shutil.rmtree(folder)
refresh()
except Exception as e:
messagebox.showerror("Uninstall", str(e), parent=win)
tk.Button(bar, text="📥 Install .pyapp", command=self.install_app, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="▶ Launch", command=launch, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="🗑 Uninstall", command=uninstall, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="↻ Refresh", command=refresh, relief="flat").pack(side="right", padx=4)
box.bind("<Double-Button-1>", lambda e: launch())
refresh()
def install_app(self):
p = filedialog.askopenfilename(
title="Install Python OS App",
filetypes=[("Python OS App", "*.pyapp"), ("ZIP package", "*.zip"), ("All files", "*.*")])
if not p: return
try:
if not zipfile.is_zipfile(p):
raise ValueError("The selected file is not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id", "name", "version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
messagebox.showinfo("Python OS", f"{manifest['name']} v{manifest['version']} installed successfully!", parent=self.root)
except Exception as e:
messagebox.showerror("Installation failed", str(e), parent=self.root)
def launch_installed_app(self, folder, manifest):
main = os.path.join(folder, "main.py")
if not os.path.isfile(main):
messagebox.showerror("App", "main.py was not found.", parent=self.root)
return
try:
namespace = {"__name__": "__main__", "__file__": main,
"PYTHON_OS_APP": self, "APP_DIR": folder}
with open(main, encoding="utf-8") as f:
source = f.read()
exec(compile(source, main, "exec"), namespace, namespace)
except Exception as e:
messagebox.showerror(f"App error: {manifest.get('name','App')}", str(e), parent=self.root)
def create_example_app(self):
p = filedialog.asksaveasfilename(
title="Create example Python OS App", defaultextension=".pyapp",
filetypes=[("Python OS App", "*.pyapp")], initialfile="HelloPythonOS.pyapp")
if not p: return
manifest = {
"id": "hello-python-os", "name": "Hello Python OS", "version": "1.0",
"description": "A sample Python OS application"
}
main = """import tkinter as tk
win = tk.Toplevel(PYTHON_OS_APP.root)
win.title("Hello Python OS")
win.geometry("430x250")
tk.Label(win, text="🎉 Hello from a Python OS App!",
font=("Segoe UI", 17, "bold")).pack(pady=50)
tk.Label(win, text="This app was installed from a .pyapp package.",
fg="#666").pack()
tk.Button(win, text="Close", command=win.destroy).pack(pady=25)
"""
try:
with zipfile.ZipFile(p, "w", zipfile.ZIP_DEFLATED) as z:
z.writestr("app.json", json.dumps(manifest, indent=2, ensure_ascii=False))
z.writestr("main.py", main)
messagebox.showinfo("Python OS", "Example .pyapp created.", parent=self.root)
except Exception as e:
messagebox.showerror("Create app", str(e), parent=self.root)
def app_store(self):
win = self.new_window("Python OS App Store", "720x470")
tk.Label(win, text="🛍 Python OS App Store",
font=("Segoe UI", 24, "bold")).pack(pady=(25, 5))
tk.Label(win, text="Local application installer",
fg="#666").pack()
tk.Label(win, text="Choose a .pyapp file to install it on Python OS.",
font=("Segoe UI", 11)).pack(pady=25)
tk.Button(win, text="📥 Install .pyapp", command=self.install_app,
width=25, pady=8).pack(pady=6)
tk.Button(win, text="🧪 Create example .pyapp",
command=self.create_example_app, width=25, pady=8).pack(pady=6)
tk.Button(win, text="📦 App Manager",
command=self.app_manager, width=25, pady=8).pack(pady=6)
tk.Label(win, text="Package = ZIP renamed to .pyapp, containing app.json + main.py",
fg="#777", font=("Segoe UI", 9)).pack(pady=25)
# ---------- Microsoft-style App Center ----------
def app_catalog(self):
"""Built-in catalog. A catalog.json can override/extend it."""
built_in = [
{"id":"hello-python-os","name":"Hello Python OS","version":"1.0",
"category":"Demo","description":"A tiny example app for Python OS.",
"type":"builtin"},
{"id":"calculator","name":"Calculator","version":"1.0",
"category":"Tools","description":"Built-in Python OS calculator.",
"type":"builtin"},
{"id":"notepad","name":"Notepad","version":"1.0",
"category":"Productivity","description":"Simple text editor.",
"type":"builtin"},
{"id":"terminal","name":"Terminal","version":"1.0",
"category":"System","description":"Python OS command terminal.",
"type":"builtin"},
]
try:
with open(self.catalog_file, "r", encoding="utf-8") as f:
external = json.load(f)
if isinstance(external, list):
by_id = {x["id"]:x for x in built_in if isinstance(x,dict) and x.get("id")}
for x in external:
if isinstance(x,dict) and x.get("id") and x.get("name"):
by_id[x["id"]] = x
return list(by_id.values())
except Exception:
pass
return built_in
def app_center(self):
win = self.new_window("Microsoft-style App Center", "950x650")
win.minsize(720, 480)
header = tk.Frame(win, bg="#176aa5", height=90)
header.pack(fill="x")
tk.Label(header, text="🛍 Python OS App Center",
bg="#0078d7", fg="white",
font=("Segoe UI", 22, "bold")).pack(side="left", padx=24, pady=22)
search_var = tk.StringVar()
search = tk.Entry(header, textvariable=search_var,
font=("Segoe UI", 11), width=30)
search.pack(side="right", padx=20, pady=27)
search.insert(0, "Search apps...")
body = tk.Frame(win, bg="#f3f3f3")
body.pack(fill="both", expand=True)
categories = tk.Frame(body, bg="#e6e6e6", width=145)
categories.pack(side="left", fill="y")
categories.pack_propagate(False)
content = tk.Frame(body, bg="#f3f3f3")
content.pack(side="left", fill="both", expand=True)
canvas = tk.Canvas(content, bg="#f3f3f3", highlightthickness=0)
scroll = tk.Scrollbar(content, orient="vertical", command=canvas.yview)
cards = tk.Frame(canvas, bg="#f3f3f3")
canvas.create_window((0,0), window=cards, anchor="nw")
canvas.configure(yscrollcommand=scroll.set)
canvas.pack(side="left", fill="both", expand=True)
scroll.pack(side="right", fill="y")
catalog = self.app_catalog()
current_category = ["All"]
def installed_ids():
return {m.get("id") for _, m in self.installed_apps()}
def launch_builtin(app_id):
mapping = {
"calculator": self.calculator,
"notepad": self.notepad,
"terminal": self.terminal,
"hello-python-os": self.create_example_app,
}
if app_id in mapping:
mapping[app_id]()
def install_catalog_item(app):
if app.get("type") == "builtin":
if app["id"] in installed_ids():
launch_builtin(app["id"])
return
# Built-ins are represented by creating a real .pyapp package.
if app["id"] == "hello-python-os":
self.create_example_app()
return
messagebox.showinfo(
"Python OS", "This built-in app is already part of Python OS.",
parent=win)
return
url = app.get("url")
if not url:
messagebox.showwarning(
"Python OS", "This catalog entry has no download URL.", parent=win)
return
self.download_and_install(url, app.get("name","App"), win)
def render():
for w in cards.winfo_children():
w.destroy()
q = search_var.get().lower().strip()
installed = installed_ids()
shown = 0
for app in catalog:
cat = app.get("category","Other")
if current_category[0] != "All" and cat != current_category[0]:
continue
if q and q not in (app.get("name","")+" "+app.get("description","")).lower():
continue
card = tk.Frame(cards, bg="white", bd=1, relief="solid",
padx=14, pady=10)
card.pack(fill="x", padx=18, pady=8)
shown += 1
icon = app.get("icon","📦")
tk.Label(card, text=icon, bg="white",
font=("Segoe UI Emoji", 30)).pack(side="left", padx=8)
info = tk.Frame(card, bg="white")
info.pack(side="left", fill="x", expand=True)
tk.Label(info, text=app.get("name","Unnamed"),
bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack(anchor="w")
tk.Label(info, text=f"v{app.get('version','1.0')} • {cat}",
bg="white", fg="#777").pack(anchor="w")
tk.Label(info, text=app.get("description",""),
bg="white", fg="#555", wraplength=470,
justify="left").pack(anchor="w", pady=(4,0))
aid = app.get("id")
if aid in installed:
button_text = "▶ Open"
elif app.get("type") == "builtin" and aid != "hello-python-os":
button_text = "Included"
else:
button_text = "📥 Install"
tk.Button(card, text=button_text,
command=lambda a=app: install_catalog_item(a),
width=12, relief="flat",
bg="#0878c9" if button_text != "Included" else "#ddd",
fg="white" if button_text != "Included" else "#555").pack(
side="right", padx=10)
if shown == 0:
tk.Label(cards, text="No apps found.",
bg="#f3f3f3", fg="#777",
font=("Segoe UI", 12)).pack(pady=40)
cards.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
cats = ["All"] + sorted({a.get("category","Other") for a in catalog})
for cat in cats:
tk.Button(categories, text=cat, command=lambda c=cat:(
current_category.__setitem__(0,c), render()),
anchor="w", relief="flat", bg="#e6e6e6",
font=("Segoe UI", 10)).pack(fill="x", padx=8, pady=3)
search_var.trace_add("write", lambda *args: render())
footer = tk.Frame(win, bg="#202020", height=45)
footer.pack(fill="x")
tk.Button(footer, text="📦 App Manager", command=self.app_manager,
relief="flat").pack(side="left", padx=10, pady=8)
tk.Label(footer, text="Python OS 10.0 • Windows 10 Edition",
bg="#202020", fg="white").pack(side="right", padx=15)
render()
def download_and_install(self, url, app_name, parent):
"""Download a .pyapp URL and pass it through the normal installer."""
def worker():
temp_path = os.path.join(
self.apps_dir, "download_" + next(tempfile._get_candidate_names()) + ".pyapp")
try:
urllib.request.urlretrieve(url, temp_path)
# Reuse installation logic by directly installing this downloaded file.
self.install_app_file(temp_path, parent)
except Exception as e:
self.root.after(0, lambda: messagebox.showerror(
"Download failed", f"{app_name}\n\n{e}", parent=parent))
finally:
try:
if os.path.exists(temp_path):
os.remove(temp_path)
except Exception:
pass
threading.Thread(target=worker, daemon=True).start()
messagebox.showinfo(
"Python OS", f"Downloading {app_name} in the background...",
parent=parent)
def install_app_file(self, p, parent=None):
try:
if not zipfile.is_zipfile(p):
raise ValueError("Not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id","name","version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
target = parent or self.root
self.root.after(0, lambda: messagebox.showinfo(
"Python OS", f"{manifest['name']} v{manifest['version']} installed!",
parent=target))
except Exception as e:
target = parent or self.root
self.root.after(0, lambda: messagebox.showerror(
"Installation failed", str(e), parent=target))
# ---------- context / shutdown ----------
# ---------- Python OS 10.0 Windows-10 style features ----------
def show_desktop(self):
for w, _ in list(self.tasks):
try:
if w.winfo_exists():
w.withdraw()
except Exception:
pass
def minimize_all(self):
self.show_desktop()
def open_run(self):
win = self.new_window("Run", "500x190")
tk.Label(win, text="Run", font=("Segoe UI", 18, "bold")).pack(anchor="w", padx=20, pady=(18, 5))
tk.Label(win, text="Type the name of a program or Python OS command.").pack(anchor="w", padx=20)
ent = tk.Entry(win, font=("Segoe UI", 11))
ent.pack(fill="x", padx=20, pady=12)
def go(e=None):
q = ent.get().strip()
if not q:
return
commands = {
"explorer": self.explorer, "notepad": self.notepad,
"calc": self.calculator, "calculator": self.calculator,
"terminal": self.terminal, "cmd": self.terminal,
"settings": self.settings, "store": self.app_center,
"app center": self.app_center
}
if q.lower() in commands:
commands[q.lower()]()
self.close_window(win)
else:
try:
if platform.system() == "Windows":
subprocess.Popen(q, shell=True)
else:
subprocess.Popen(q, shell=True)
self.close_window(win)
except Exception as ex:
messagebox.showerror("Run", str(ex), parent=win)
tk.Button(win, text="OK", command=go, width=10).pack(side="right", padx=10)
tk.Button(win, text="Cancel", command=lambda:self.close_window(win), width=10).pack(side="right")
ent.bind("<Return>", go)
ent.focus_force()
def alt_tab(self, event=None):
live=[]
for w, _ in list(self.tasks):
try:
if w.winfo_exists() and w.state() != "withdrawn":
live.append(w)
except Exception:
pass
if not live:
return "break"
self.alt_tab_index=(self.alt_tab_index+1) % len(live)
self.focus(live[self.alt_tab_index])
return "break"
def power_menu_open(self):
if self.power_menu and self.power_menu.winfo_exists():
self.power_menu.destroy(); self.power_menu=None; return
m=tk.Toplevel(self.root)
self.power_menu=m
m.overrideredirect(True)
m.configure(bg="#f4f4f4", bd=1, relief="solid")
w=290; h=270
x=self.root.winfo_rootx()+self.root.winfo_width()-w-12
y=self.root.winfo_rooty()+self.root.winfo_height()-h-62
m.geometry(f"{w}x{h}+{max(0,x)}+{max(0,y)}")
tk.Label(m,text="Power",bg="#f4f4f4",fg="#222",font=("Segoe UI",17,"bold")).pack(anchor="w",padx=18,pady=(16,8))
tk.Label(m,text="What do you want to do?",bg="#f4f4f4",fg="#666").pack(anchor="w",padx=18,pady=(0,10))
def act(fn):
if m.winfo_exists(): m.destroy()
self.power_menu=None
fn()
for text,fn in [("⏾ Sleep",self.sleep_os),("↻ Restart",self.restart_os),("🔒 Lock",self.lock_screen),("⏻ Shut down",self.shutdown)]:
tk.Button(m,text=text,command=lambda f=fn:act(f),anchor="w",bg="white",fg="#222",
activebackground="#dceefa",relief="flat",font=("Segoe UI",11),height=2).pack(fill="x",padx=12,pady=2)
m.bind("<Escape>",lambda e:m.destroy())
m.focus_force()
def sleep_os(self):
self.show_desktop()
self.notify("Power", "Python OS is in sleep mode.")
def restart_os(self):
self.close_start()
self.clear()
self.windows=[]; self.tasks=[]
self.boot()
def taskbar_menu(self, event):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="Toolbars")
m.add_separator()
m.add_command(label="Task Manager", command=self.task_manager)
m.add_command(label="Show the desktop", command=self.show_desktop)
m.add_separator()
m.add_command(label="Taskbar settings", command=self.settings)
m.tk_popup(event.x_root, event.y_root)
def task_manager(self):
win = self.new_window("Task Manager", "650x430")
tk.Label(win, text="Task Manager", font=("Segoe UI", 22, "bold")).pack(anchor="w", padx=20, pady=18)
box = tk.Listbox(win, font=("Consolas", 10))
box.pack(fill="both", expand=True, padx=20, pady=5)
def refresh():
box.delete(0, "end")
box.insert("end", "Python OS processes")
box.insert("end", "-" * 55)
for w, b in self.tasks:
try:
if w.winfo_exists():
box.insert("end", f"APP {w.title()}")
except Exception:
pass
box.insert("end", "")
box.insert("end", f"Open windows: {len(self.tasks)}")
box.insert("end", f"Python: {platform.python_version()}")
tk.Button(win, text="↻ Refresh", command=refresh).pack(anchor="e", padx=20, pady=8)
refresh()
def context(self, e):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="View")
m.add_command(label="Sort by")
m.add_separator()
m.add_command(label="Refresh", command=lambda:self.desktop_frame.update())
m.add_separator()
m.add_command(label="Open File Explorer", command=self.explorer)
m.add_command(label="Open Terminal", command=self.terminal)
m.add_command(label="Personalize", command=self.personalize)
m.add_command(label="About Python OS", command=self.system_info)
m.add_separator()
m.add_command(label="Show desktop", command=self.show_desktop)
m.add_command(label="Shut Down", command=self.shutdown)
m.tk_popup(e.x_root, e.y_root)
def shutdown(self):
if messagebox.askyesno("Python OS","Shut down Python OS?",parent=self.root):
self.root.configure(bg="#080808")
for w in self.root.winfo_children():
w.destroy()
tk.Label(self.root,text="⏻",fg="white",bg="#080808",font=("Segoe UI",70)).pack(pady=(220,10))
tk.Label(self.root,text="Python OS is shutting down...",fg="white",bg="#080808",font=("Segoe UI",16)).pack()
self.root.after(900,self.root.destroy)
# ---------- Python OS 10 mega features ----------
def _window_shortcuts(self, win):
win.bind("<Control-w>", lambda e: self.close_window(win))
win.bind("<Control-m>", lambda e: win.iconify())
win.bind("<Control-Shift-m>", lambda e: self._toggle_max(win))
win.bind("<Alt-Left>", lambda e: self._snap(win, "left"))
win.bind("<Alt-Right>", lambda e: self._snap(win, "right"))
win.bind("<Alt-Up>", lambda e: self._snap(win, "max"))
win.bind("<Alt-Down>", lambda e: self._snap(win, "restore"))
self.window_desktops[win] = self.virtual_desktop
def _toggle_max(self, win):
try: win.state("normal" if win.state()=="zoomed" else "zoomed")
except Exception: pass
def _snap(self, win, side):
sw=max(800,self.root.winfo_width()); sh=max(500,self.root.winfo_height()-48)
if side=="left": win.geometry(f"{sw//2}x{sh}+0+0")
elif side=="right": win.geometry(f"{sw//2}x{sh}+{sw//2}+0")
elif side=="max": win.geometry(f"{sw}x{sh}+0+0")
else: win.geometry("760x500+80+60")
def virtual_desktops(self):
win=self.new_window("Virtual Desktops","500x350")
tk.Label(win,text="🖥 Virtual Desktops",font=("Segoe UI",22,"bold")).pack(pady=18)
tk.Label(win,text="Switch workspace without closing your apps.",fg="#666").pack(pady=(0,15))
row=tk.Frame(win); row.pack(pady=10)
for i in range(1,self.desktop_count+1):
tk.Button(row,text=f"Desktop {i}",width=12,command=lambda n=i:self.switch_desktop(n,win)).pack(side="left",padx=5)
tk.Label(win,text=f"Current desktop: {self.virtual_desktop}",font=("Segoe UI",11,"bold")).pack(pady=15)
tk.Button(win,text="+ New desktop",command=lambda:self._add_virtual_desktop(win)).pack()
def _add_virtual_desktop(self, win):
if self.desktop_count<6: self.desktop_count+=1
self.close_window(win); self.virtual_desktops()
def switch_desktop(self,n,dialog=None):
self.virtual_desktop=n
for w in list(self.windows):
if not w.winfo_exists(): continue
if self.window_desktops.get(w,1)==n: w.deiconify()
else: w.withdraw()
if dialog and dialog.winfo_exists(): self.close_window(dialog)
self.notify("Virtual Desktop",f"Switched to Desktop {n}.")
def paint(self):
win=self.new_window("Paint","820x600")
bar=tk.Frame(win,bg="#eeeeee"); bar.pack(fill="x")
color=tk.StringVar(value="#111111"); size=tk.IntVar(value=4)
canvas=tk.Canvas(win,bg="white",cursor="crosshair",highlightthickness=0); canvas.pack(fill="both",expand=True)
last=[None,None]
def pick():
c=colorchooser.askcolor(parent=win)[1]
if c: color.set(c)
def down(e): last[:]=[e.x,e.y]
def move(e):
if last[0] is not None:
canvas.create_line(last[0],last[1],e.x,e.y,fill=color.get(),width=size.get(),capstyle="round")
last[:]=[e.x,e.y]
def up(e): last[:]=[None,None]
tk.Button(bar,text="🎨 Color",command=pick,relief="flat").pack(side="left",padx=4,pady=4)
tk.Label(bar,text="Size").pack(side="left")
tk.Scale(bar,from_=1,to=30,variable=size,orient="horizontal",length=120).pack(side="left")
tk.Button(bar,text="New",command=lambda:canvas.delete("all"),relief="flat").pack(side="left",padx=4)
canvas.bind("<ButtonPress-1>",down); canvas.bind("<B1-Motion>",move); canvas.bind("<ButtonRelease-1>",up)
def calendar_app(self):
import calendar as cal
from datetime import datetime
now=datetime.now(); win=self.new_window("Calendar","620x500")
head=tk.Frame(win); head.pack(fill="x",pady=12)
year=tk.IntVar(value=now.year); month=tk.IntVar(value=now.month)
view=tk.Text(win,font=("Consolas",13),height=15,bg="white",relief="flat"); view.pack(fill="both",expand=True,padx=20)
def draw(): view.delete("1.0","end"); view.insert("end",cal.month(year.get(),month.get()))
def prev():
if month.get()==1: month.set(12); year.set(year.get()-1)
else: month.set(month.get()-1)
draw()
def nxt():
if month.get()==12: month.set(1); year.set(year.get()+1)
else: month.set(month.get()+1)
draw()
tk.Button(head,text="◀",command=prev).pack(side="left",padx=20); tk.Label(head,textvariable=month,font=("Segoe UI",14,"bold")).pack(side="left")
tk.Label(head,textvariable=year,font=("Segoe UI",14,"bold")).pack(side="left",padx=8); tk.Button(head,text="▶",command=nxt).pack(side="left")
draw()
def image_viewer(self):
p=filedialog.askopenfilename(title="Open image",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if not p:return
try:
img=tk.PhotoImage(file=p); win=self.new_window("Image Viewer","850x650")
tk.Label(win,text=os.path.basename(p),font=("Segoe UI",14,"bold")).pack(pady=8)
holder=tk.Label(win,image=img,bg="#222"); holder.image=img; holder.pack(fill="both",expand=True,padx=10,pady=10)
except Exception as e: messagebox.showerror("Image Viewer",str(e),parent=self.root)
def system_monitor(self):
win=self.new_window("System Monitor","700x480")
tree=ttk.Treeview(win,columns=("value",),show="headings")
tree.heading("value",text="System information"); tree.column("value",width=600); tree.pack(fill="both",expand=True,padx=15,pady=15)
def refresh():
if not win.winfo_exists(): return
for x in tree.get_children(): tree.delete(x)
rows=[("Python",platform.python_version()),("Platform",platform.platform()),("Architecture",platform.machine()),("Processor",platform.processor() or "Unknown"),("Working directory",os.getcwd()),("Open windows",sum(1 for w in self.windows if w.winfo_exists())),("Virtual desktop",self.virtual_desktop),("Notifications",len(self.notifications))]
for k,v in rows: tree.insert("","end",values=(f"{k}: {v}",))
win.after(1500,refresh)
refresh()
def user_profile(self):
win=self.new_window("User Profile","480x360")
tk.Label(win,text="👤 User Profile",font=("Segoe UI",22,"bold")).pack(pady=20)
name=tk.StringVar(value=self.username)
tk.Label(win,text="Display name").pack(anchor="w",padx=30)
tk.Entry(win,textvariable=name,font=("Segoe UI",12)).pack(fill="x",padx=30,pady=8)
def save():
self.username=name.get().strip() or "User"; self.save_settings(); self.notify("Account","Profile updated."); self.close_window(win)
tk.Button(win,text="Save profile",command=save,bg="#0878c9",fg="white",relief="flat",padx=20,pady=8).pack(pady=15)
def keyboard_shortcuts(self):
win=self.new_window("Keyboard Shortcuts","620x500")
tk.Label(win,text="⌨ Keyboard shortcuts",font=("Segoe UI",22,"bold")).pack(pady=18)
items=[("Ctrl+Alt+D","Show desktop"),("Ctrl+Alt+R","Run"),("Ctrl+Alt+T","Terminal"),("Ctrl+Alt+L","Lock"),("Ctrl+Alt+S","Power menu"),("Ctrl+Alt+V","Virtual desktops"),("Ctrl+Alt+P","Paint"),("Ctrl+Alt+C","Calendar"),("Alt+Tab","Cycle windows"),("Ctrl+W","Close"),("Ctrl+M","Minimize"),("Ctrl+Shift+M","Maximize/restore"),("Alt+← / →","Snap left/right"),("Alt+↑ / ↓","Maximize/restore")]
for k,d in items: tk.Label(win,text=f"{k:<22} {d}",font=("Consolas",11),anchor="w").pack(fill="x",padx=35,pady=3)
def advanced_settings(self):
win=self.new_window("System Settings","720x560")
nb=ttk.Notebook(win); nb.pack(fill="both",expand=True,padx=10,pady=10)
p1=tk.Frame(nb); p2=tk.Frame(nb); p3=tk.Frame(nb); nb.add(p1,text="Account"); nb.add(p2,text="System"); nb.add(p3,text="Shortcuts")
tk.Label(p1,text="👤 Account",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p1,text="Edit user profile",command=self.user_profile).pack(anchor="w",padx=25,pady=6)
tk.Label(p1,text=f"Current user: {self.username}",fg="#666").pack(anchor="w",padx=25,pady=6)
tk.Label(p2,text="⚙ System",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p2,text="System Monitor",command=self.system_monitor).pack(anchor="w",padx=25,pady=5); tk.Button(p2,text="Virtual Desktops",command=self.virtual_desktops).pack(anchor="w",padx=25,pady=5)
tk.Label(p3,text="⌨ Shortcuts",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p3,text="View all shortcuts",command=self.keyboard_shortcuts).pack(anchor="w",padx=25,pady=5)
if __name__=="__main__":
root=tk.Tk()
PythonOS(root)
root.mainloop()
if x == 3 :
import tkinter as tk
from tkinter import simpledialog
from tkinter import messagebox, filedialog, colorchooser, ttk
import os, time, platform, subprocess, json, math, zipfile, shutil, tempfile, re, urllib.request, threading
class PythonOS:
def __init__(self, root):
self.root = root
self.root.title("Python OS 11.0")
self.root.geometry("1366x768")
self.root.minsize(1050, 650)
self.wallpaper = "#0078d7"
self.username = "User"
self.notifications = []
self.wallpaper_image = None
self.windows = []
self.tasks = []
self.start_open = False
self.menu = None
self.power_menu = None
self.desktop_icons = []
self.alt_tab_index = 0
self.virtual_desktop = 1
self.desktop_count = 3
self.window_desktops = {}
self.wallpaper_path = ""
self.volume = 70
self.brightness = 80
self.settings_file = os.path.join(os.path.expanduser("~"), ".python_os_settings.json")
self.apps_dir = os.path.join(os.path.expanduser("~"), ".python_os_apps")
self.apps_data = os.path.join(self.apps_dir, "installed")
self.catalog_file = os.path.join(self.apps_dir, "catalog.json")
os.makedirs(self.apps_data, exist_ok=True)
self.load_settings()
if self.wallpaper_path and os.path.isfile(self.wallpaper_path):
try: self.wallpaper_image=tk.PhotoImage(file=self.wallpaper_path)
except Exception: self.wallpaper_image=None
self.boot()
# ---------- startup ----------
def load_settings(self):
try:
with open(self.settings_file, "r", encoding="utf-8") as f:
d = json.load(f)
self.wallpaper = d.get("wallpaper", self.wallpaper)
self.username = d.get("username", "User")
self.wallpaper_path = d.get("wallpaper_path", "")
self.volume = int(d.get("volume", 70))
self.brightness = int(d.get("brightness", 80))
except Exception:
pass
def save_settings(self):
try:
with open(self.settings_file, "w", encoding="utf-8") as f:
json.dump({"wallpaper": self.wallpaper, "username": self.username, "wallpaper_path": self.wallpaper_path, "volume": self.volume, "brightness": self.brightness}, f)
except Exception:
pass
def boot(self):
self.clear()
self.root.configure(bg="#080808")
box = tk.Frame(self.root, bg="#080808")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#080808",
font=("Segoe UI", 80)).pack(pady=(150, 0))
tk.Label(box, text="Python OS", fg="white", bg="#080808",
font=("Segoe UI", 28, "bold")).pack()
tk.Label(box, text="Loading desktop...", fg="#aaa", bg="#080808",
font=("Segoe UI", 10)).pack(pady=12)
bar = tk.Frame(box, bg="#333", width=300, height=5)
bar.pack()
bar.pack_propagate(False)
fill = tk.Frame(bar, bg="#1683d8", width=0, height=5)
fill.pack(side="left")
def animate(n=0):
if n <= 300 and box.winfo_exists():
fill.config(width=n)
self.root.after(7, lambda: animate(n + 4))
animate()
self.root.after(1500, self.login)
def login(self):
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 65)).pack(pady=(115, 0))
tk.Label(box, text="Python OS", fg="white", bg="#176aa5",
font=("Segoe UI", 27, "bold")).pack()
card = tk.Frame(box, bg="white", width=350, height=190)
card.pack(pady=22)
card.pack_propagate(False)
tk.Label(card, text="👤", bg="white", font=("Segoe UI Emoji", 30)).pack(pady=12)
tk.Label(card, text=self.username, bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack()
b = tk.Button(card, text="Sign in", command=self.desktop,
bg="#0878c9", fg="white", relief="flat",
font=("Segoe UI", 11, "bold"), padx=38, pady=7)
b.pack(pady=12)
self.root.bind("<Return>", lambda e: self.desktop())
def clear(self):
for w in self.root.winfo_children():
w.destroy()
# ---------- desktop ----------
def desktop(self):
self.root.unbind("<Return>")
self.clear()
self.root.bind_all("<Control-Alt-d>", lambda e: self.show_desktop())
self.root.bind_all("<Control-Alt-r>", lambda e: self.open_run())
self.root.bind_all("<Control-Alt-t>", lambda e: self.terminal())
self.root.bind_all("<Control-Alt-l>", lambda e: self.lock_screen())
self.root.bind_all("<Alt-KeyPress-Tab>", self.alt_tab)
self.root.bind_all("<Control-Alt-s>", lambda e: self.power_menu_open())
self.root.bind_all("<Control-Alt-v>", lambda e: self.virtual_desktops())
self.root.bind_all("<Control-Alt-p>", lambda e: self.paint())
self.root.bind_all("<Control-Alt-c>", lambda e: self.calendar_app())
self.root.configure(bg=self.wallpaper)
self.desktop_frame = tk.Frame(self.root, bg=self.wallpaper)
self.desktop_frame.pack(fill="both", expand=True)
if self.wallpaper_image:
self._wall_img_label = tk.Label(self.desktop_frame, image=self.wallpaper_image, bd=0)
self._wall_img_label.place(relx=0, rely=0, relwidth=1, relheight=1)
self._wall_img_label.lower()
# wallpaper branding
tk.Label(self.desktop_frame, text="Python OS",
bg=self.wallpaper, fg="white",
font=("Segoe UI", 40, "bold")).place(relx=.5, rely=.40, anchor="center")
tk.Label(self.desktop_frame, text="Version 10.0",
bg=self.wallpaper, fg="#d9efff",
font=("Segoe UI", 11)).place(relx=.5, rely=.48, anchor="center")
icons = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("⚙", "Settings", self.settings),
("💻", "Terminal", self.terminal),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
for i, item in enumerate(icons):
x = 22 + (i // 6) * 105
y = 20 + (i % 6) * 92
self.icon(*item, x=x, y=y)
# taskbar
self.taskbar = tk.Frame(self.root, bg="#1f1f1f", height=48)
self.taskbar.pack(side="bottom", fill="x")
self.taskbar.pack_propagate(False)
tk.Button(self.taskbar, text="⊞", command=self.toggle_start,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 23)).pack(side="left", padx=6)
tk.Button(self.taskbar, text="🔍", command=self.search,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 13)).pack(side="left", padx=3)
self.task_area = tk.Frame(self.taskbar, bg="#1f1f1f")
self.task_area.pack(side="left", fill="both", expand=True, padx=8)
# Windows 10 style pinned taskbar buttons
for text, cmd in [("▣", self.explorer), ("🌐", self.browser), ("🛍", self.app_center)]:
tk.Button(self.taskbar, text=text, command=cmd, bg="#1f1f1f", fg="white",
activebackground="#333333", relief="flat", bd=0,
font=("Segoe UI Emoji", 13)).pack(side="left", padx=2)
tray = tk.Frame(self.taskbar, bg="#202020")
tray.pack(side="right", fill="y")
tk.Button(tray, text="🔔", command=self.notification_center, bg="#202020", fg="white", relief="flat", bd=0).pack(side="left", padx=3)
tk.Button(tray, text="⌁ 🔊", command=self.quick_controls, bg="#202020", fg="white", relief="flat", bd=0,
font=("Segoe UI", 11)).pack(side="left", padx=4)
tk.Button(tray, text="⏻", command=self.power_menu_open, bg="#202020", fg="white",
activebackground="#3b3b3b", relief="flat", bd=0, font=("Segoe UI", 14)).pack(side="left", padx=4)
self.clock = tk.Label(tray, bg="#202020", fg="white",
font=("Segoe UI", 9), justify="right")
self.clock.pack(side="left", padx=10)
self.tick()
self.desktop_frame.bind("<Button-3>", self.context)
self.desktop_frame.bind("<Double-Button-1>", lambda e: self.close_start())
def icon(self, emoji, name, command, x, y):
f = tk.Frame(self.desktop_frame, bg=self.wallpaper, width=92, height=82)
f.place(x=x, y=y)
f.pack_propagate(False)
btn = tk.Button(f, text=emoji, command=command,
bg=self.wallpaper, fg="white", activebackground="#2b89c9",
relief="flat", bd=0, font=("Segoe UI Emoji", 25))
btn.pack(fill="x")
tk.Label(f, text=name, bg=self.wallpaper, fg="white",
font=("Segoe UI", 9), wraplength=88).pack()
self.desktop_icons.append(f)
def start_drag(e):
f._dx, f._dy = e.x, e.y
def drag(e):
nx=max(4, min(self.root.winfo_width()-100, f.winfo_x()+e.x-f._dx))
ny=max(4, min(self.root.winfo_height()-145, f.winfo_y()+e.y-f._dy))
f.place(x=nx, y=ny)
for w in (f, btn):
w.bind("<ButtonPress-1>", start_drag, add="+")
w.bind("<B1-Motion>", drag, add="+")
def quick_controls(self):
win=self.new_window("Quick Settings", "430x300")
tk.Label(win,text="⚡ Quick settings",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=20,pady=18)
for text,cmd in [("🎨 Personalization",self.personalize),("🔔 Notifications",self.notification_center),("⚙ Settings",self.settings),("ℹ About",self.system_info)]:
tk.Button(win,text=text,command=cmd,anchor="w",relief="flat",font=("Segoe UI",11)).pack(fill="x",padx=20,pady=4)
def tick(self):
if hasattr(self, "clock") and self.clock.winfo_exists():
self.clock.config(text=time.strftime("%H:%M\n%d/%m/%Y"))
self.root.after(1000, self.tick)
# ---------- Python OS 11.0 system features ----------
def notify(self, title, text):
self.notifications.append((title, text, time.strftime("%H:%M")))
if len(self.notifications) > 30:
self.notifications = self.notifications[-30:]
def notification_center(self):
win = self.new_window("Notification Center", "520x520")
win.configure(bg="#f4f4f4")
tk.Label(win, text="🔔 Notifications", bg="#f4f4f4", fg="#222",
font=("Segoe UI", 20, "bold")).pack(anchor="w", padx=20, pady=18)
body = tk.Frame(win, bg="#f4f4f4")
body.pack(fill="both", expand=True, padx=14)
if not self.notifications:
tk.Label(body, text="You're all caught up.", bg="#f4f4f4", fg="#777",
font=("Segoe UI", 12)).pack(pady=50)
else:
for title, text, stamp in reversed(self.notifications):
card = tk.Frame(body, bg="white", bd=1, relief="solid")
card.pack(fill="x", pady=5)
tk.Label(card, text=f"{title} • {stamp}", bg="white", fg="#222",
font=("Segoe UI", 11, "bold")).pack(anchor="w", padx=12, pady=(9,2))
tk.Label(card, text=text, bg="white", fg="#555", wraplength=450,
justify="left").pack(anchor="w", padx=12, pady=(0,9))
tk.Button(win, text="Clear notifications", command=lambda:self.clear_notifications(win),
relief="flat").pack(anchor="e", padx=18, pady=12)
def clear_notifications(self, win=None):
self.notifications.clear()
if win and win.winfo_exists():
self.close_window(win)
self.notification_center()
def lock_screen(self):
self.close_start()
for w, _ in list(self.tasks):
try:
if w.winfo_exists(): w.withdraw()
except Exception: pass
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 80)).pack(pady=(125, 0))
tk.Label(box, text=self.username, fg="white", bg="#176aa5",
font=("Segoe UI", 24, "bold")).pack(pady=8)
tk.Label(box, text=time.strftime("%A, %d %B\n%H:%M"), fg="white", bg="#176aa5",
font=("Segoe UI", 18)).pack(pady=10)
b=tk.Button(box, text="🔓 Sign in", command=self.unlock_screen,
font=("Segoe UI", 12, "bold"), padx=30, pady=10)
b.pack(pady=25)
self.root.bind("<Return>", lambda e: self.unlock_screen())
def unlock_screen(self):
self.root.unbind("<Return>")
self.desktop()
self.notify("Python OS", "You signed in successfully.")
def personalize(self):
win=self.new_window("Personalization", "620x470")
tk.Label(win,text="🎨 Personalization",font=("Segoe UI",22,"bold")).pack(anchor="w",padx=20,pady=18)
tk.Label(win,text="Choose your desktop appearance.",fg="#666").pack(anchor="w",padx=20)
row=tk.Frame(win); row.pack(fill="x",padx=20,pady=20)
tk.Button(row,text="Choose color",command=self.choose_wallpaper).pack(side="left",padx=5)
tk.Button(row,text="Choose wallpaper image",command=self.choose_wallpaper_image).pack(side="left",padx=5)
tk.Button(row,text="Reset",command=lambda:self.reset_wallpaper()).pack(side="left",padx=5)
tk.Label(win,text="Keyboard shortcuts",font=("Segoe UI",14,"bold")).pack(anchor="w",padx=20,pady=(15,5))
tk.Label(win,text="Ctrl+Alt+D Show desktop\nCtrl+Alt+R Run\nCtrl+Alt+T Terminal\nCtrl+Alt+L Lock screen",justify="left").pack(anchor="w",padx=20)
def choose_wallpaper(self):
c=colorchooser.askcolor(title="Choose desktop color")
if c and c[1]:
self.wallpaper=c[1]
self.wallpaper_image=None
self.save_settings()
self.desktop()
self.notify("Personalization", "Desktop color changed.")
def choose_wallpaper_image(self):
path=filedialog.askopenfilename(title="Choose wallpaper",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if path:
try:
self.wallpaper_image=tk.PhotoImage(file=path)
self.wallpaper_path=path
self.wallpaper="#000000"
self.save_settings()
self.desktop()
self.notify("Personalization", "Wallpaper image applied.")
except Exception as e:
messagebox.showerror("Wallpaper", f"Could not load image.\n{e}")
def reset_wallpaper(self):
self.wallpaper="#0078d7"
self.wallpaper_image=None
self.wallpaper_path=""
self.save_settings(); self.desktop()
def system_info(self):
win=self.new_window("About Python OS", "560x390")
tk.Label(win,text="⊞ Python OS 11.0",font=("Segoe UI",24,"bold")).pack(pady=25)
info=f"Windows 10 Edition\n\nPython: {platform.python_version()}\nPlatform: {platform.platform()}\nArchitecture: {platform.machine()}\nUser: {self.username}"
tk.Label(win,text=info,justify="left",font=("Segoe UI",11)).pack(anchor="w",padx=35)
# ---------- windows ----------
def new_window(self, title, size="700x480"):
self.close_start()
win = tk.Toplevel(self.root)
win.title(title)
win.geometry(size)
win.minsize(350, 230)
win.protocol("WM_DELETE_WINDOW", lambda: self.close_window(win))
win.bind("<FocusIn>", lambda e: self.focus(win))
self.windows.append(win)
b = tk.Button(self.task_area, text=title[:18], command=lambda: self.focus(win),
bg="#303030", fg="white", activebackground="#505050",
relief="flat", bd=0, font=("Segoe UI", 9), padx=9)
b.pack(side="left", padx=2, pady=6)
self.tasks.append((win, b))
if hasattr(self, "window_desktops"):
self._window_shortcuts(win)
win.focus_force()
return win
def focus(self, win):
if win.winfo_exists():
win.deiconify()
win.lift()
win.focus_force()
def close_window(self, win):
for w, b in list(self.tasks):
if w is win:
b.destroy()
self.tasks.remove((w, b))
if win in self.windows:
self.windows.remove(win)
if win.winfo_exists():
win.destroy()
# ---------- start ----------
def toggle_start(self):
if self.start_open:
self.close_start()
return
self.start_open = True
self.start = tk.Frame(self.root, bg="#f4f4f4", width=620, height=620,
bd=1, relief="solid")
self.start.place(x=6, y=max(5, self.root.winfo_height()-665))
self.start.lift()
head = tk.Frame(self.start, bg="#0078d7", height=76)
head.pack(fill="x")
tk.Label(head, text=f"👤 {self.username}", bg="#0078d7", fg="white",
font=("Segoe UI", 14, "bold")).pack(side="left", padx=20, pady=22)
search = tk.Entry(self.start, font=("Segoe UI", 11))
search.pack(fill="x", padx=16, pady=12)
search.insert(0, "Search apps...")
search.bind("<FocusIn>", lambda e: search.delete(0, "end") if search.get()=="Search apps..." else None)
body = tk.Frame(self.start, bg="#f4f4f4")
body.pack(fill="both", expand=True)
apps = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("💻", "Terminal", self.terminal),
("⚙", "Settings", self.settings),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
buttons = []
for ico, name, cmd in apps:
b = tk.Button(body, text=f"{ico} {name}", command=cmd,
anchor="w", bg="#f4f4f4", fg="#222",
activebackground="#dceefa", relief="flat",
font=("Segoe UI", 11), height=2)
b.pack(fill="x", padx=12, pady=1)
buttons.append((name.lower(), b))
def filter_apps(e=None):
q = search.get().lower()
for n, b in buttons:
b.pack_forget()
if q in n:
b.pack(fill="x", padx=12, pady=1)
search.bind("<KeyRelease>", filter_apps)
bottom = tk.Frame(self.start, bg="#e7e7e7", height=48)
bottom.pack(side="bottom", fill="x")
tk.Button(bottom, text="⚙ Settings", command=self.settings,
bg="#e7e7e7", relief="flat").pack(side="left", padx=12, pady=9)
tk.Button(bottom, text="🔒 Lock", command=self.lock_screen,
bg="#e7e7e7", relief="flat").pack(side="right", padx=4, pady=9)
tk.Button(bottom, text="⏻ Shut down", command=self.shutdown,
bg="#e7e7e7", relief="flat").pack(side="right", padx=12, pady=9)
def close_start(self):
if self.start_open and self.start.winfo_exists():
self.start.destroy()
self.start_open = False
# ---------- apps ----------
def explorer(self):
win = self.new_window("File Explorer 11", "980x600")
toolbar = tk.Frame(win, bg="#f2f2f2"); toolbar.pack(fill="x")
path = tk.StringVar(value=os.path.expanduser("~"))
history=[]; future=[]; clipboard={"path":None,"cut":False}
tk.Button(toolbar,text="←",command=lambda:go_back(),relief="flat").pack(side="left",padx=2)
tk.Button(toolbar,text="→",command=lambda:go_forward(),relief="flat").pack(side="left",padx=2)
tk.Button(toolbar,text="🏠",command=lambda:load(os.path.expanduser("~"),True),relief="flat").pack(side="left",padx=2)
ent=tk.Entry(toolbar,textvariable=path,font=("Segoe UI",10)); ent.pack(side="left",fill="x",expand=True,padx=5,pady=6)
tk.Button(toolbar,text="↻",command=lambda:load(path.get()),relief="flat").pack(side="left")
body=tk.PanedWindow(win,orient="horizontal",sashwidth=5); body.pack(fill="both",expand=True)
side=tk.Frame(body,bg="#f7f7f7",width=170); body.add(side,stretch="never")
box=ttk.Treeview(body,columns=("type","size"),show="tree headings"); box.heading("#0",text="Name"); box.heading("type",text="Type"); box.heading("size",text="Size"); box.column("type",width=100); box.column("size",width=110); body.add(box)
for label,pth in [("Desktop",os.path.join(os.path.expanduser("~"),"Desktop")),("Documents",os.path.join(os.path.expanduser("~"),"Documents")),("Downloads",os.path.join(os.path.expanduser("~"),"Downloads")),("Pictures",os.path.join(os.path.expanduser("~"),"Pictures")),("Home",os.path.expanduser("~"))]:
if os.path.isdir(pth): tk.Button(side,text=" "+label,anchor="w",relief="flat",bg="#f7f7f7",command=lambda q=pth:load(q,True)).pack(fill="x",pady=1)
bar=tk.Frame(win,bg="#eeeeee"); bar.pack(fill="x")
status=tk.Label(bar,text="Ready",anchor="w",bg="#eeeeee",fg="#555"); status.pack(side="left",padx=8,pady=5)
def selected():
ids=box.selection(); return os.path.join(path.get(),box.item(ids[0],"text")) if ids else None
def load(p,record=False):
try:
p=os.path.abspath(os.path.expanduser(p))
if not os.path.isdir(p): raise ValueError("Folder not found")
if record and path.get()!=p: history.append(path.get()); future.clear()
path.set(p); box.delete(*box.get_children())
for name in sorted(os.listdir(p),key=lambda x:(not os.path.isdir(os.path.join(p,x)),x.lower())):
full=os.path.join(p,name); isdir=os.path.isdir(full); size="—" if isdir else str(os.path.getsize(full))+" B"
box.insert("","end",text=name,values=("Folder" if isdir else "File",size))
status.config(text=f"{len(box.get_children())} items • {p}")
except Exception as e: messagebox.showerror("File Explorer",str(e),parent=win)
def go_back():
if history: future.append(path.get()); load(history.pop(),False)
def go_forward():
if future: history.append(path.get()); load(future.pop(),False)
def open_item(e=None):
p=selected()
if not p:return
if os.path.isdir(p): load(p,True)
else:
try:
if platform.system()=="Windows": os.startfile(p)
elif platform.system()=="Darwin": subprocess.Popen(["open",p])
else: subprocess.Popen(["xdg-open",p])
except Exception as ex: messagebox.showerror("Open",str(ex),parent=win)
def new_folder():
name= simpledialog.askstring("New Folder","Folder name:",parent=win) if 'simpledialog' in globals() else None
if name:
try: os.makedirs(os.path.join(path.get(),name),exist_ok=False); load(path.get())
except Exception as e: messagebox.showerror("New Folder",str(e),parent=win)
def delete_item():
p=selected()
if not p:return
if messagebox.askyesno("Delete",f"Delete {os.path.basename(p)}?",parent=win):
try: shutil.rmtree(p) if os.path.isdir(p) else os.remove(p); load(path.get())
except Exception as e: messagebox.showerror("Delete",str(e),parent=win)
def rename_item():
p=selected()
if not p:return
name=simpledialog.askstring("Rename","New name:",initialvalue=os.path.basename(p),parent=win) if 'simpledialog' in globals() else None
if name:
try: os.rename(p,os.path.join(path.get(),name)); load(path.get())
except Exception as e: messagebox.showerror("Rename",str(e),parent=win)
def copy_item(cut=False):
p=selected()
if p: clipboard.update(path=p,cut=cut); status.config(text=("Cut: " if cut else "Copied: ")+os.path.basename(p))
def paste_item():
p=clipboard.get("path")
if not p:return
try:
dest=os.path.join(path.get(),os.path.basename(p));
if clipboard.get("cut"): shutil.move(p,dest); clipboard["path"]=None
elif os.path.isdir(p): shutil.copytree(p,dest)
else: shutil.copy2(p,dest)
load(path.get())
except Exception as e: messagebox.showerror("Paste",str(e),parent=win)
for text,cmd in [("+ Folder",new_folder),("Rename",rename_item),("Delete",delete_item),("Copy",lambda:copy_item(False)),("Cut",lambda:copy_item(True)),("Paste",paste_item)]: tk.Button(toolbar,text=text,command=cmd,relief="flat").pack(side="left",padx=2)
ent.bind("<Return>",lambda e:load(path.get(),True)); box.bind("<Double-1>",open_item)
load(path.get())
def notepad(self):
win = self.new_window("Notepad", "800x560")
bar = tk.Frame(win, bg="#eeeeee"); bar.pack(fill="x")
text = tk.Text(win, font=("Consolas", 12), undo=True, wrap="word")
text.pack(fill="both", expand=True)
def new(): text.delete("1.0","end")
def openf():
p=filedialog.askopenfilename(parent=win,filetypes=[("Text","*.txt"),("All","*.*")])
if p:
try:
text.delete("1.0","end"); text.insert("1.0",open(p,encoding="utf-8").read())
except Exception as e: messagebox.showerror("Notepad",str(e),parent=win)
def save():
p=filedialog.asksaveasfilename(parent=win,defaultextension=".txt",
filetypes=[("Text","*.txt"),("All","*.*")])
if p: open(p,"w",encoding="utf-8").write(text.get("1.0","end-1c"))
for n,c in [("New",new),("Open",openf),("Save",save)]:
tk.Button(bar,text=n,command=c,relief="flat").pack(side="left",padx=4,pady=4)
def calculator(self):
win=self.new_window("Calculator","380x520")
exp=tk.StringVar()
tk.Entry(win,textvariable=exp,justify="right",font=("Segoe UI",24),bd=0).pack(fill="x",padx=12,pady=15,ipady=8)
grid=tk.Frame(win); grid.pack(fill="both",expand=True,padx=8,pady=8)
keys=[["C","(",")","/"],["7","8","9","*"],["4","5","6","-"],["1","2","3","+"],["0",".","⌫","="]]
def press(k):
if k=="C": exp.set("")
elif k=="⌫": exp.set(exp.get()[:-1])
elif k=="=":
try:
if any(c not in "0123456789.+-*/() " for c in exp.get()): raise ValueError()
exp.set(str(eval(exp.get(),{"__builtins__":{}},{})))
except: exp.set("Error")
else: exp.set(exp.get()+k)
for r,row in enumerate(keys):
for c,k in enumerate(row):
tk.Button(grid,text=k,command=lambda x=k:press(x),
font=("Segoe UI",13),relief="flat").grid(row=r,column=c,sticky="nsew",padx=2,pady=2)
for r in range(5): grid.rowconfigure(r,weight=1)
for c in range(4): grid.columnconfigure(c,weight=1)
def browser(self):
win=self.new_window("Python Browser","760x520")
tk.Label(win,text="🌐 Python Browser",font=("Segoe UI",20,"bold")).pack(pady=18)
tk.Label(win,text="This lightweight browser opens web pages in your default browser.",
fg="#666").pack()
url=tk.Entry(win,font=("Segoe UI",12))
url.pack(fill="x",padx=35,pady=15)
url.insert(0,"https://[Log in to view URL]")
def go():
u=url.get().strip()
if not u.startswith(("http://","https://")): u="https://"+u
try:
import webbrowser; webbrowser.open(u)
except Exception as e: messagebox.showerror("Browser",str(e),parent=win)
tk.Button(win,text="Open website",command=go,width=18).pack()
def settings(self):
win=self.new_window("Settings","700x520")
tk.Label(win,text="Settings",font=("Segoe UI",26,"bold")).pack(anchor="w",padx=25,pady=20)
tk.Label(win,text="Personalization",font=("Segoe UI",13,"bold")).pack(anchor="w",padx=25,pady=5)
colors=[("Windows Blue","#0878c9"),("Dark Blue","#123b63"),("Green","#197a3a"),
("Purple","#663399"),("Dark","#222222")]
def setbg(c):
self.wallpaper=c
self.desktop_frame.config(bg=c)
for w in self.desktop_frame.winfo_children():
try: w.config(bg=c)
except: pass
self.save_settings()
for n,c in colors:
tk.Button(win,text=n,command=lambda c=c:setbg(c),width=24,anchor="w").pack(anchor="w",padx=25,pady=3)
tk.Button(win,text="Choose custom color",
command=lambda:(lambda c:c and setbg(c))(colorchooser.askcolor(parent=win)[1])).pack(anchor="w",padx=25,pady=8)
tk.Label(win,text=f"Python {platform.python_version()} • {platform.system()}",
fg="#777").pack(anchor="w",padx=25,pady=18)
def terminal(self):
win=self.new_window("Terminal","800x500")
out=tk.Text(win,bg="#0c0c0c",fg="#eee",insertbackground="white",font=("Consolas",11))
out.pack(fill="both",expand=True)
out.insert("end","Python OS Terminal 3.0\nType 'help' for commands.\n\n> ")
ent=tk.Entry(win,bg="#0c0c0c",fg="white",insertbackground="white",font=("Consolas",11))
ent.pack(fill="x")
def write(s): out.insert("end",s+"\n"); out.see("end")
def run(e=None):
cmd=ent.get().strip(); ent.delete(0,"end")
if not cmd:return
out.insert("end",cmd+"\n")
if cmd=="help": write("help, clear, time, date, system, pwd, dir, echo <text>, python")
elif cmd=="clear": out.delete("1.0","end")
elif cmd=="time": write(time.strftime("%H:%M:%S"))
elif cmd=="date": write(time.strftime("%Y-%m-%d"))
elif cmd=="system": write(f"{platform.system()} {platform.release()} | Python {platform.python_version()}")
elif cmd=="pwd": write(os.getcwd())
elif cmd=="dir":
try: write("\n".join(os.listdir()))
except Exception as e: write("Error: "+str(e))
elif cmd=="python": write("Python "+platform.python_version())
elif cmd.startswith("echo "): write(cmd[5:])
else: write("Unknown command. Type 'help'.")
out.insert("end","\n> "); out.see("end")
ent.bind("<Return>",run); ent.focus()
def search(self):
win=self.new_window("Search","600x400")
tk.Label(win,text="Search Python OS",font=("Segoe UI",22,"bold")).pack(pady=20)
ent=tk.Entry(win,font=("Segoe UI",13)); ent.pack(fill="x",padx=30)
box=tk.Listbox(win,font=("Segoe UI",11)); box.pack(fill="both",expand=True,padx=30,pady=15)
apps=[("File Explorer",self.explorer),("Notepad",self.notepad),("Calculator",self.calculator),
("Browser",self.browser),("Settings",self.settings),("App Center",self.app_center),("App Manager",self.app_manager),
("Terminal",self.terminal),("Recycle Bin",self.recycle),("Paint",self.paint),("Calendar",self.calendar_app),("System Monitor",self.system_monitor),("Image Viewer",self.image_viewer)]
def do(e=None):
q=ent.get().lower(); box.delete(0,"end")
for n,_ in apps:
if q in n.lower(): box.insert("end",n)
def launch(e=None):
s=box.curselection()
if not s:return
for n,c in apps:
if n==box.get(s[0]): c(); break
ent.bind("<KeyRelease>",do); box.bind("<Double-Button-1>",launch)
def recycle(self):
win=self.new_window("Recycle Bin","500x330")
tk.Label(win,text="🗑",font=("Segoe UI Emoji",55)).pack(pady=30)
tk.Label(win,text="Recycle Bin is empty",font=("Segoe UI",13)).pack()
tk.Button(win,text="Close",command=lambda:self.close_window(win)).pack(pady=25)
# ---------- Python OS App System ----------
def installed_apps(self):
result = []
for folder in sorted(os.listdir(self.apps_data)):
p = os.path.join(self.apps_data, folder)
mf = os.path.join(p, "app.json")
if os.path.isdir(p) and os.path.isfile(mf):
try:
with open(mf, encoding="utf-8") as f:
m = json.load(f)
if m.get("id") and m.get("name"):
result.append((p, m))
except Exception:
pass
return result
def app_manager(self):
win = self.new_window("App Manager", "820x560")
tk.Label(win, text="📦 Python OS App Manager",
font=("Segoe UI", 23, "bold")).pack(anchor="w", padx=25, pady=(20, 3))
tk.Label(win, text="Install, launch and uninstall .pyapp applications",
fg="#666").pack(anchor="w", padx=25)
bar = tk.Frame(win); bar.pack(fill="x", padx=20, pady=12)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=20, pady=5)
apps = []
def refresh():
nonlocal apps
apps = self.installed_apps()
box.delete(0, "end")
if not apps:
box.insert("end", " No applications installed")
for folder, m in apps:
box.insert("end", f" {m['name']} — v{m.get('version','1.0')} — {m.get('description','')}")
def selected():
s = box.curselection()
return apps[s[0]] if s and s[0] < len(apps) else None
def launch():
item = selected()
if item:
self.launch_installed_app(*item)
def uninstall():
item = selected()
if not item: return
folder, m = item
if messagebox.askyesno("Uninstall", f"Uninstall {m['name']}?", parent=win):
try:
shutil.rmtree(folder)
refresh()
except Exception as e:
messagebox.showerror("Uninstall", str(e), parent=win)
tk.Button(bar, text="📥 Install .pyapp", command=self.install_app, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="▶ Launch", command=launch, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="🗑 Uninstall", command=uninstall, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="↻ Refresh", command=refresh, relief="flat").pack(side="right", padx=4)
box.bind("<Double-Button-1>", lambda e: launch())
refresh()
def install_app(self):
p = filedialog.askopenfilename(
title="Install Python OS App",
filetypes=[("Python OS App", "*.pyapp"), ("ZIP package", "*.zip"), ("All files", "*.*")])
if not p: return
try:
if not zipfile.is_zipfile(p):
raise ValueError("The selected file is not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id", "name", "version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
messagebox.showinfo("Python OS", f"{manifest['name']} v{manifest['version']} installed successfully!", parent=self.root)
except Exception as e:
messagebox.showerror("Installation failed", str(e), parent=self.root)
def launch_installed_app(self, folder, manifest):
main = os.path.join(folder, "main.py")
if not os.path.isfile(main):
messagebox.showerror("App", "main.py was not found.", parent=self.root)
return
try:
namespace = {"__name__": "__main__", "__file__": main,
"PYTHON_OS_APP": self, "APP_DIR": folder}
with open(main, encoding="utf-8") as f:
source = f.read()
exec(compile(source, main, "exec"), namespace, namespace)
except Exception as e:
messagebox.showerror(f"App error: {manifest.get('name','App')}", str(e), parent=self.root)
def create_example_app(self):
p = filedialog.asksaveasfilename(
title="Create example Python OS App", defaultextension=".pyapp",
filetypes=[("Python OS App", "*.pyapp")], initialfile="HelloPythonOS.pyapp")
if not p: return
manifest = {
"id": "hello-python-os", "name": "Hello Python OS", "version": "1.0",
"description": "A sample Python OS application"
}
main = """import tkinter as tk
from tkinter import simpledialog
win = tk.Toplevel(PYTHON_OS_APP.root)
win.title("Hello Python OS")
win.geometry("430x250")
tk.Label(win, text="🎉 Hello from a Python OS App!",
font=("Segoe UI", 17, "bold")).pack(pady=50)
tk.Label(win, text="This app was installed from a .pyapp package.",
fg="#666").pack()
tk.Button(win, text="Close", command=win.destroy).pack(pady=25)
"""
try:
with zipfile.ZipFile(p, "w", zipfile.ZIP_DEFLATED) as z:
z.writestr("app.json", json.dumps(manifest, indent=2, ensure_ascii=False))
z.writestr("main.py", main)
messagebox.showinfo("Python OS", "Example .pyapp created.", parent=self.root)
except Exception as e:
messagebox.showerror("Create app", str(e), parent=self.root)
def app_store(self):
win = self.new_window("Python OS App Store", "720x470")
tk.Label(win, text="🛍 Python OS App Store",
font=("Segoe UI", 24, "bold")).pack(pady=(25, 5))
tk.Label(win, text="Local application installer",
fg="#666").pack()
tk.Label(win, text="Choose a .pyapp file to install it on Python OS.",
font=("Segoe UI", 11)).pack(pady=25)
tk.Button(win, text="📥 Install .pyapp", command=self.install_app,
width=25, pady=8).pack(pady=6)
tk.Button(win, text="🧪 Create example .pyapp",
command=self.create_example_app, width=25, pady=8).pack(pady=6)
tk.Button(win, text="📦 App Manager",
command=self.app_manager, width=25, pady=8).pack(pady=6)
tk.Label(win, text="Package = ZIP renamed to .pyapp, containing app.json + main.py",
fg="#777", font=("Segoe UI", 9)).pack(pady=25)
# ---------- Microsoft-style App Center ----------
def app_catalog(self):
"""Built-in catalog. A catalog.json can override/extend it."""
built_in = [
{"id":"hello-python-os","name":"Hello Python OS","version":"1.0",
"category":"Demo","description":"A tiny example app for Python OS.",
"type":"builtin"},
{"id":"calculator","name":"Calculator","version":"1.0",
"category":"Tools","description":"Built-in Python OS calculator.",
"type":"builtin"},
{"id":"notepad","name":"Notepad","version":"1.0",
"category":"Productivity","description":"Simple text editor.",
"type":"builtin"},
{"id":"terminal","name":"Terminal","version":"1.0",
"category":"System","description":"Python OS command terminal.",
"type":"builtin"},
]
try:
with open(self.catalog_file, "r", encoding="utf-8") as f:
external = json.load(f)
if isinstance(external, list):
by_id = {x["id"]:x for x in built_in if isinstance(x,dict) and x.get("id")}
for x in external:
if isinstance(x,dict) and x.get("id") and x.get("name"):
by_id[x["id"]] = x
return list(by_id.values())
except Exception:
pass
return built_in
def app_center(self):
win = self.new_window("Microsoft-style App Center", "950x650")
win.minsize(720, 480)
header = tk.Frame(win, bg="#176aa5", height=90)
header.pack(fill="x")
tk.Label(header, text="🛍 Python OS App Center",
bg="#0078d7", fg="white",
font=("Segoe UI", 22, "bold")).pack(side="left", padx=24, pady=22)
search_var = tk.StringVar()
search = tk.Entry(header, textvariable=search_var,
font=("Segoe UI", 11), width=30)
search.pack(side="right", padx=20, pady=27)
search.insert(0, "Search apps...")
body = tk.Frame(win, bg="#f3f3f3")
body.pack(fill="both", expand=True)
categories = tk.Frame(body, bg="#e6e6e6", width=145)
categories.pack(side="left", fill="y")
categories.pack_propagate(False)
content = tk.Frame(body, bg="#f3f3f3")
content.pack(side="left", fill="both", expand=True)
canvas = tk.Canvas(content, bg="#f3f3f3", highlightthickness=0)
scroll = tk.Scrollbar(content, orient="vertical", command=canvas.yview)
cards = tk.Frame(canvas, bg="#f3f3f3")
canvas.create_window((0,0), window=cards, anchor="nw")
canvas.configure(yscrollcommand=scroll.set)
canvas.pack(side="left", fill="both", expand=True)
scroll.pack(side="right", fill="y")
catalog = self.app_catalog()
current_category = ["All"]
def installed_ids():
return {m.get("id") for _, m in self.installed_apps()}
def launch_builtin(app_id):
mapping = {
"calculator": self.calculator,
"notepad": self.notepad,
"terminal": self.terminal,
"hello-python-os": self.create_example_app,
}
if app_id in mapping:
mapping[app_id]()
def install_catalog_item(app):
if app.get("type") == "builtin":
if app["id"] in installed_ids():
launch_builtin(app["id"])
return
# Built-ins are represented by creating a real .pyapp package.
if app["id"] == "hello-python-os":
self.create_example_app()
return
messagebox.showinfo(
"Python OS", "This built-in app is already part of Python OS.",
parent=win)
return
url = app.get("url")
if not url:
messagebox.showwarning(
"Python OS", "This catalog entry has no download URL.", parent=win)
return
self.download_and_install(url, app.get("name","App"), win)
def render():
for w in cards.winfo_children():
w.destroy()
q = search_var.get().lower().strip()
installed = installed_ids()
shown = 0
for app in catalog:
cat = app.get("category","Other")
if current_category[0] != "All" and cat != current_category[0]:
continue
if q and q not in (app.get("name","")+" "+app.get("description","")).lower():
continue
card = tk.Frame(cards, bg="white", bd=1, relief="solid",
padx=14, pady=10)
card.pack(fill="x", padx=18, pady=8)
shown += 1
icon = app.get("icon","📦")
tk.Label(card, text=icon, bg="white",
font=("Segoe UI Emoji", 30)).pack(side="left", padx=8)
info = tk.Frame(card, bg="white")
info.pack(side="left", fill="x", expand=True)
tk.Label(info, text=app.get("name","Unnamed"),
bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack(anchor="w")
tk.Label(info, text=f"v{app.get('version','1.0')} • {cat}",
bg="white", fg="#777").pack(anchor="w")
tk.Label(info, text=app.get("description",""),
bg="white", fg="#555", wraplength=470,
justify="left").pack(anchor="w", pady=(4,0))
aid = app.get("id")
if aid in installed:
button_text = "▶ Open"
elif app.get("type") == "builtin" and aid != "hello-python-os":
button_text = "Included"
else:
button_text = "📥 Install"
tk.Button(card, text=button_text,
command=lambda a=app: install_catalog_item(a),
width=12, relief="flat",
bg="#0878c9" if button_text != "Included" else "#ddd",
fg="white" if button_text != "Included" else "#555").pack(
side="right", padx=10)
if shown == 0:
tk.Label(cards, text="No apps found.",
bg="#f3f3f3", fg="#777",
font=("Segoe UI", 12)).pack(pady=40)
cards.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
cats = ["All"] + sorted({a.get("category","Other") for a in catalog})
for cat in cats:
tk.Button(categories, text=cat, command=lambda c=cat:(
current_category.__setitem__(0,c), render()),
anchor="w", relief="flat", bg="#e6e6e6",
font=("Segoe UI", 10)).pack(fill="x", padx=8, pady=3)
search_var.trace_add("write", lambda *args: render())
footer = tk.Frame(win, bg="#202020", height=45)
footer.pack(fill="x")
tk.Button(footer, text="📦 App Manager", command=self.app_manager,
relief="flat").pack(side="left", padx=10, pady=8)
tk.Label(footer, text="Python OS 11.0 • Windows 10 Edition",
bg="#202020", fg="white").pack(side="right", padx=15)
render()
def download_and_install(self, url, app_name, parent):
"""Download a .pyapp URL and pass it through the normal installer."""
def worker():
temp_path = os.path.join(
self.apps_dir, "download_" + next(tempfile._get_candidate_names()) + ".pyapp")
try:
urllib.request.urlretrieve(url, temp_path)
# Reuse installation logic by directly installing this downloaded file.
self.install_app_file(temp_path, parent)
except Exception as e:
self.root.after(0, lambda: messagebox.showerror(
"Download failed", f"{app_name}\n\n{e}", parent=parent))
finally:
try:
if os.path.exists(temp_path):
os.remove(temp_path)
except Exception:
pass
threading.Thread(target=worker, daemon=True).start()
messagebox.showinfo(
"Python OS", f"Downloading {app_name} in the background...",
parent=parent)
def install_app_file(self, p, parent=None):
try:
if not zipfile.is_zipfile(p):
raise ValueError("Not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id","name","version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
target = parent or self.root
self.root.after(0, lambda: messagebox.showinfo(
"Python OS", f"{manifest['name']} v{manifest['version']} installed!",
parent=target))
except Exception as e:
target = parent or self.root
self.root.after(0, lambda: messagebox.showerror(
"Installation failed", str(e), parent=target))
# ---------- context / shutdown ----------
# ---------- Python OS 11.0 Windows-10 style features ----------
def show_desktop(self):
for w, _ in list(self.tasks):
try:
if w.winfo_exists():
w.withdraw()
except Exception:
pass
def minimize_all(self):
self.show_desktop()
def open_run(self):
win = self.new_window("Run", "500x190")
tk.Label(win, text="Run", font=("Segoe UI", 18, "bold")).pack(anchor="w", padx=20, pady=(18, 5))
tk.Label(win, text="Type the name of a program or Python OS command.").pack(anchor="w", padx=20)
ent = tk.Entry(win, font=("Segoe UI", 11))
ent.pack(fill="x", padx=20, pady=12)
def go(e=None):
q = ent.get().strip()
if not q:
return
commands = {
"explorer": self.explorer, "notepad": self.notepad,
"calc": self.calculator, "calculator": self.calculator,
"terminal": self.terminal, "cmd": self.terminal,
"settings": self.settings, "store": self.app_center,
"app center": self.app_center
}
if q.lower() in commands:
commands[q.lower()]()
self.close_window(win)
else:
try:
if platform.system() == "Windows":
subprocess.Popen(q, shell=True)
else:
subprocess.Popen(q, shell=True)
self.close_window(win)
except Exception as ex:
messagebox.showerror("Run", str(ex), parent=win)
tk.Button(win, text="OK", command=go, width=10).pack(side="right", padx=10)
tk.Button(win, text="Cancel", command=lambda:self.close_window(win), width=10).pack(side="right")
ent.bind("<Return>", go)
ent.focus_force()
def alt_tab(self, event=None):
live=[]
for w, _ in list(self.tasks):
try:
if w.winfo_exists() and w.state() != "withdrawn":
live.append(w)
except Exception:
pass
if not live:
return "break"
self.alt_tab_index=(self.alt_tab_index+1) % len(live)
self.focus(live[self.alt_tab_index])
return "break"
def power_menu_open(self):
if self.power_menu and self.power_menu.winfo_exists():
self.power_menu.destroy(); self.power_menu=None; return
m=tk.Toplevel(self.root)
self.power_menu=m
m.overrideredirect(True)
m.configure(bg="#f4f4f4", bd=1, relief="solid")
w=290; h=270
x=self.root.winfo_rootx()+self.root.winfo_width()-w-12
y=self.root.winfo_rooty()+self.root.winfo_height()-h-62
m.geometry(f"{w}x{h}+{max(0,x)}+{max(0,y)}")
tk.Label(m,text="Power",bg="#f4f4f4",fg="#222",font=("Segoe UI",17,"bold")).pack(anchor="w",padx=18,pady=(16,8))
tk.Label(m,text="What do you want to do?",bg="#f4f4f4",fg="#666").pack(anchor="w",padx=18,pady=(0,10))
def act(fn):
if m.winfo_exists(): m.destroy()
self.power_menu=None
fn()
for text,fn in [("⏾ Sleep",self.sleep_os),("↻ Restart",self.restart_os),("🔒 Lock",self.lock_screen),("⏻ Shut down",self.shutdown)]:
tk.Button(m,text=text,command=lambda f=fn:act(f),anchor="w",bg="white",fg="#222",
activebackground="#dceefa",relief="flat",font=("Segoe UI",11),height=2).pack(fill="x",padx=12,pady=2)
m.bind("<Escape>",lambda e:m.destroy())
m.focus_force()
def sleep_os(self):
self.show_desktop()
self.notify("Power", "Python OS is in sleep mode.")
def restart_os(self):
self.close_start()
self.clear()
self.windows=[]; self.tasks=[]
self.boot()
def taskbar_menu(self, event):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="Toolbars")
m.add_separator()
m.add_command(label="Task Manager", command=self.task_manager)
m.add_command(label="Show the desktop", command=self.show_desktop)
m.add_separator()
m.add_command(label="Taskbar settings", command=self.settings)
m.tk_popup(event.x_root, event.y_root)
def task_manager(self):
win = self.new_window("Task Manager", "650x430")
tk.Label(win, text="Task Manager", font=("Segoe UI", 22, "bold")).pack(anchor="w", padx=20, pady=18)
box = tk.Listbox(win, font=("Consolas", 10))
box.pack(fill="both", expand=True, padx=20, pady=5)
def refresh():
box.delete(0, "end")
box.insert("end", "Python OS processes")
box.insert("end", "-" * 55)
for w, b in self.tasks:
try:
if w.winfo_exists():
box.insert("end", f"APP {w.title()}")
except Exception:
pass
box.insert("end", "")
box.insert("end", f"Open windows: {len(self.tasks)}")
box.insert("end", f"Python: {platform.python_version()}")
tk.Button(win, text="↻ Refresh", command=refresh).pack(anchor="e", padx=20, pady=8)
refresh()
def context(self, e):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="View")
m.add_command(label="Sort by")
m.add_separator()
m.add_command(label="Refresh", command=lambda:self.desktop_frame.update())
m.add_separator()
m.add_command(label="Open File Explorer", command=self.explorer)
m.add_command(label="Open Terminal", command=self.terminal)
m.add_command(label="Personalize", command=self.personalize)
m.add_command(label="About Python OS", command=self.system_info)
m.add_separator()
m.add_command(label="Show desktop", command=self.show_desktop)
m.add_command(label="Shut Down", command=self.shutdown)
m.tk_popup(e.x_root, e.y_root)
def shutdown(self):
if messagebox.askyesno("Python OS","Shut down Python OS?",parent=self.root):
self.root.configure(bg="#080808")
for w in self.root.winfo_children():
w.destroy()
tk.Label(self.root,text="⏻",fg="white",bg="#080808",font=("Segoe UI",70)).pack(pady=(220,10))
tk.Label(self.root,text="Python OS is shutting down...",fg="white",bg="#080808",font=("Segoe UI",16)).pack()
self.root.after(900,self.root.destroy)
# ---------- Python OS 10 mega features ----------
def _window_shortcuts(self, win):
win.bind("<Control-w>", lambda e: self.close_window(win))
win.bind("<Control-m>", lambda e: win.iconify())
win.bind("<Control-Shift-m>", lambda e: self._toggle_max(win))
win.bind("<Alt-Left>", lambda e: self._snap(win, "left"))
win.bind("<Alt-Right>", lambda e: self._snap(win, "right"))
win.bind("<Alt-Up>", lambda e: self._snap(win, "max"))
win.bind("<Alt-Down>", lambda e: self._snap(win, "restore"))
self.window_desktops[win] = self.virtual_desktop
def _toggle_max(self, win):
try: win.state("normal" if win.state()=="zoomed" else "zoomed")
except Exception: pass
def _snap(self, win, side):
sw=max(800,self.root.winfo_width()); sh=max(500,self.root.winfo_height()-48)
if side=="left": win.geometry(f"{sw//2}x{sh}+0+0")
elif side=="right": win.geometry(f"{sw//2}x{sh}+{sw//2}+0")
elif side=="max": win.geometry(f"{sw}x{sh}+0+0")
else: win.geometry("760x500+80+60")
def virtual_desktops(self):
win=self.new_window("Virtual Desktops","500x350")
tk.Label(win,text="🖥 Virtual Desktops",font=("Segoe UI",22,"bold")).pack(pady=18)
tk.Label(win,text="Switch workspace without closing your apps.",fg="#666").pack(pady=(0,15))
row=tk.Frame(win); row.pack(pady=10)
for i in range(1,self.desktop_count+1):
tk.Button(row,text=f"Desktop {i}",width=12,command=lambda n=i:self.switch_desktop(n,win)).pack(side="left",padx=5)
tk.Label(win,text=f"Current desktop: {self.virtual_desktop}",font=("Segoe UI",11,"bold")).pack(pady=15)
tk.Button(win,text="+ New desktop",command=lambda:self._add_virtual_desktop(win)).pack()
def _add_virtual_desktop(self, win):
if self.desktop_count<6: self.desktop_count+=1
self.close_window(win); self.virtual_desktops()
def switch_desktop(self,n,dialog=None):
self.virtual_desktop=n
for w in list(self.windows):
if not w.winfo_exists(): continue
if self.window_desktops.get(w,1)==n: w.deiconify()
else: w.withdraw()
if dialog and dialog.winfo_exists(): self.close_window(dialog)
self.notify("Virtual Desktop",f"Switched to Desktop {n}.")
def paint(self):
win=self.new_window("Paint","820x600")
bar=tk.Frame(win,bg="#eeeeee"); bar.pack(fill="x")
color=tk.StringVar(value="#111111"); size=tk.IntVar(value=4)
canvas=tk.Canvas(win,bg="white",cursor="crosshair",highlightthickness=0); canvas.pack(fill="both",expand=True)
last=[None,None]
def pick():
c=colorchooser.askcolor(parent=win)[1]
if c: color.set(c)
def down(e): last[:]=[e.x,e.y]
def move(e):
if last[0] is not None:
canvas.create_line(last[0],last[1],e.x,e.y,fill=color.get(),width=size.get(),capstyle="round")
last[:]=[e.x,e.y]
def up(e): last[:]=[None,None]
tk.Button(bar,text="🎨 Color",command=pick,relief="flat").pack(side="left",padx=4,pady=4)
tk.Label(bar,text="Size").pack(side="left")
tk.Scale(bar,from_=1,to=30,variable=size,orient="horizontal",length=120).pack(side="left")
tk.Button(bar,text="New",command=lambda:canvas.delete("all"),relief="flat").pack(side="left",padx=4)
canvas.bind("<ButtonPress-1>",down); canvas.bind("<B1-Motion>",move); canvas.bind("<ButtonRelease-1>",up)
def calendar_app(self):
import calendar as cal
from datetime import datetime
now=datetime.now(); win=self.new_window("Calendar","620x500")
head=tk.Frame(win); head.pack(fill="x",pady=12)
year=tk.IntVar(value=now.year); month=tk.IntVar(value=now.month)
view=tk.Text(win,font=("Consolas",13),height=15,bg="white",relief="flat"); view.pack(fill="both",expand=True,padx=20)
def draw(): view.delete("1.0","end"); view.insert("end",cal.month(year.get(),month.get()))
def prev():
if month.get()==1: month.set(12); year.set(year.get()-1)
else: month.set(month.get()-1)
draw()
def nxt():
if month.get()==12: month.set(1); year.set(year.get()+1)
else: month.set(month.get()+1)
draw()
tk.Button(head,text="◀",command=prev).pack(side="left",padx=20); tk.Label(head,textvariable=month,font=("Segoe UI",14,"bold")).pack(side="left")
tk.Label(head,textvariable=year,font=("Segoe UI",14,"bold")).pack(side="left",padx=8); tk.Button(head,text="▶",command=nxt).pack(side="left")
draw()
def image_viewer(self):
p=filedialog.askopenfilename(title="Open image",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if not p:return
try:
img=tk.PhotoImage(file=p); win=self.new_window("Image Viewer","850x650")
tk.Label(win,text=os.path.basename(p),font=("Segoe UI",14,"bold")).pack(pady=8)
holder=tk.Label(win,image=img,bg="#222"); holder.image=img; holder.pack(fill="both",expand=True,padx=10,pady=10)
except Exception as e: messagebox.showerror("Image Viewer",str(e),parent=self.root)
def system_monitor(self):
win=self.new_window("System Monitor","700x480")
tree=ttk.Treeview(win,columns=("value",),show="headings")
tree.heading("value",text="System information"); tree.column("value",width=600); tree.pack(fill="both",expand=True,padx=15,pady=15)
def refresh():
if not win.winfo_exists(): return
for x in tree.get_children(): tree.delete(x)
rows=[("Python",platform.python_version()),("Platform",platform.platform()),("Architecture",platform.machine()),("Processor",platform.processor() or "Unknown"),("Working directory",os.getcwd()),("Open windows",sum(1 for w in self.windows if w.winfo_exists())),("Virtual desktop",self.virtual_desktop),("Notifications",len(self.notifications))]
for k,v in rows: tree.insert("","end",values=(f"{k}: {v}",))
win.after(1500,refresh)
refresh()
def user_profile(self):
win=self.new_window("User Profile","480x360")
tk.Label(win,text="👤 User Profile",font=("Segoe UI",22,"bold")).pack(pady=20)
name=tk.StringVar(value=self.username)
tk.Label(win,text="Display name").pack(anchor="w",padx=30)
tk.Entry(win,textvariable=name,font=("Segoe UI",12)).pack(fill="x",padx=30,pady=8)
def save():
self.username=name.get().strip() or "User"; self.save_settings(); self.notify("Account","Profile updated."); self.close_window(win)
tk.Button(win,text="Save profile",command=save,bg="#0878c9",fg="white",relief="flat",padx=20,pady=8).pack(pady=15)
def keyboard_shortcuts(self):
win=self.new_window("Keyboard Shortcuts","620x500")
tk.Label(win,text="⌨ Keyboard shortcuts",font=("Segoe UI",22,"bold")).pack(pady=18)
items=[("Ctrl+Alt+D","Show desktop"),("Ctrl+Alt+R","Run"),("Ctrl+Alt+T","Terminal"),("Ctrl+Alt+L","Lock"),("Ctrl+Alt+S","Power menu"),("Ctrl+Alt+V","Virtual desktops"),("Ctrl+Alt+P","Paint"),("Ctrl+Alt+C","Calendar"),("Alt+Tab","Cycle windows"),("Ctrl+W","Close"),("Ctrl+M","Minimize"),("Ctrl+Shift+M","Maximize/restore"),("Alt+← / →","Snap left/right"),("Alt+↑ / ↓","Maximize/restore")]
for k,d in items: tk.Label(win,text=f"{k:<22} {d}",font=("Consolas",11),anchor="w").pack(fill="x",padx=35,pady=3)
def advanced_settings(self):
win=self.new_window("System Settings","720x560")
nb=ttk.Notebook(win); nb.pack(fill="both",expand=True,padx=10,pady=10)
p1=tk.Frame(nb); p2=tk.Frame(nb); p3=tk.Frame(nb); nb.add(p1,text="Account"); nb.add(p2,text="System"); nb.add(p3,text="Shortcuts")
tk.Label(p1,text="👤 Account",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p1,text="Edit user profile",command=self.user_profile).pack(anchor="w",padx=25,pady=6)
tk.Label(p1,text=f"Current user: {self.username}",fg="#666").pack(anchor="w",padx=25,pady=6)
tk.Label(p2,text="⚙ System",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p2,text="System Monitor",command=self.system_monitor).pack(anchor="w",padx=25,pady=5); tk.Button(p2,text="Virtual Desktops",command=self.virtual_desktops).pack(anchor="w",padx=25,pady=5)
tk.Label(p3,text="⌨ Shortcuts",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p3,text="View all shortcuts",command=self.keyboard_shortcuts).pack(anchor="w",padx=25,pady=5)
if __name__=="__main__":
root=tk.Tk()
PythonOS(root)
root.mainloop()
elif x == 4 :
import tkinter as tk
from tkinter import simpledialog
from tkinter import messagebox, filedialog, colorchooser, ttk
import os, time, platform, subprocess, json, math, zipfile, shutil, tempfile, re, urllib.request, threading, datetime
class PythonOS:
def __init__(self, root):
self.root = root
self.root.title("Python OS 12 Pro Max")
self.root.geometry("1366x768")
self.root.minsize(1050, 650)
self.wallpaper = "#0078d7"
self.username = "User"
self.notifications = []
self.wallpaper_image = None
self.windows = []
self.tasks = []
self.start_open = False
self.menu = None
self.power_menu = None
self.desktop_icons = []
self.alt_tab_index = 0
self.virtual_desktop = 1
self.desktop_count = 3
self.window_desktops = {}
self.wallpaper_path = ""
self.volume = 70
self.brightness = 80
self.theme = "Light"
self.clipboard_history = []
self.recent_files = []
self.pinned_apps = ["File Explorer", "Browser", "App Center"]
self.game_mode = False
self.start_tiles = ["File Explorer", "Browser", "Settings", "Terminal", "Paint", "Calculator"]
self.settings_file = os.path.join(os.path.expanduser("~"), ".python_os_settings.json")
self.apps_dir = os.path.join(os.path.expanduser("~"), ".python_os_apps")
self.apps_data = os.path.join(self.apps_dir, "installed")
self.catalog_file = os.path.join(self.apps_dir, "catalog.json")
os.makedirs(self.apps_data, exist_ok=True)
self.load_settings()
if self.wallpaper_path and os.path.isfile(self.wallpaper_path):
try: self.wallpaper_image=tk.PhotoImage(file=self.wallpaper_path)
except Exception: self.wallpaper_image=None
self.boot()
# ---------- startup ----------
def load_settings(self):
try:
with open(self.settings_file, "r", encoding="utf-8") as f:
d = json.load(f)
self.wallpaper = d.get("wallpaper", self.wallpaper)
self.username = d.get("username", "User")
self.wallpaper_path = d.get("wallpaper_path", "")
self.volume = int(d.get("volume", 70))
self.brightness = int(d.get("brightness", 80))
self.theme = d.get("theme", "Light")
self.pinned_apps = d.get("pinned_apps", self.pinned_apps)
except Exception:
pass
def save_settings(self):
try:
with open(self.settings_file, "w", encoding="utf-8") as f:
json.dump({"wallpaper": self.wallpaper, "username": self.username, "wallpaper_path": self.wallpaper_path, "volume": self.volume, "brightness": self.brightness, "theme": self.theme, "pinned_apps": self.pinned_apps}, f)
except Exception:
pass
def boot(self):
self.clear()
self.root.configure(bg="#080808")
box = tk.Frame(self.root, bg="#080808")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#080808",
font=("Segoe UI", 80)).pack(pady=(150, 0))
tk.Label(box, text="Python OS", fg="white", bg="#080808",
font=("Segoe UI", 28, "bold")).pack()
tk.Label(box, text="Loading desktop...", fg="#aaa", bg="#080808",
font=("Segoe UI", 10)).pack(pady=12)
bar = tk.Frame(box, bg="#333", width=300, height=5)
bar.pack()
bar.pack_propagate(False)
fill = tk.Frame(bar, bg="#1683d8", width=0, height=5)
fill.pack(side="left")
def animate(n=0):
if n <= 300 and box.winfo_exists():
fill.config(width=n)
self.root.after(7, lambda: animate(n + 4))
animate()
self.root.after(1500, self.login)
def login(self):
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 65)).pack(pady=(115, 0))
tk.Label(box, text="Python OS", fg="white", bg="#176aa5",
font=("Segoe UI", 27, "bold")).pack()
card = tk.Frame(box, bg="white", width=350, height=190)
card.pack(pady=22)
card.pack_propagate(False)
tk.Label(card, text="👤", bg="white", font=("Segoe UI Emoji", 30)).pack(pady=12)
tk.Label(card, text=self.username, bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack()
b = tk.Button(card, text="Sign in", command=self.desktop,
bg="#0878c9", fg="white", relief="flat",
font=("Segoe UI", 11, "bold"), padx=38, pady=7)
b.pack(pady=12)
self.root.bind("<Return>", lambda e: self.desktop())
def clear(self):
for w in self.root.winfo_children():
w.destroy()
# ---------- desktop ----------
def desktop(self):
self.root.unbind("<Return>")
self.clear()
self.root.bind_all("<Control-Alt-d>", lambda e: self.show_desktop())
self.root.bind_all("<Control-Alt-r>", lambda e: self.open_run())
self.root.bind_all("<Control-Alt-t>", lambda e: self.terminal())
self.root.bind_all("<Control-Alt-l>", lambda e: self.lock_screen())
self.root.bind_all("<Alt-KeyPress-Tab>", self.alt_tab)
self.root.bind_all("<Control-Alt-s>", lambda e: self.power_menu_open())
self.root.bind_all("<Control-Alt-v>", lambda e: self.virtual_desktops())
self.root.bind_all("<Control-Alt-p>", lambda e: self.paint())
self.root.bind_all("<Control-Alt-c>", lambda e: self.calendar_app())
self.root.bind_all("<Control-Alt-a>", lambda e: self.action_center())
self.root.bind_all("<Control-Alt-f>", lambda e: self.file_search_pro())
self.root.bind_all("<Control-Alt-g>", lambda e: self.game_mode_toggle())
self.root.configure(bg=self.wallpaper)
self.desktop_frame = tk.Frame(self.root, bg=self.wallpaper)
self.desktop_frame.pack(fill="both", expand=True)
if self.wallpaper_image:
self._wall_img_label = tk.Label(self.desktop_frame, image=self.wallpaper_image, bd=0)
self._wall_img_label.place(relx=0, rely=0, relwidth=1, relheight=1)
self._wall_img_label.lower()
# wallpaper branding
tk.Label(self.desktop_frame, text="Python OS",
bg=self.wallpaper, fg="white",
font=("Segoe UI", 40, "bold")).place(relx=.5, rely=.40, anchor="center")
tk.Label(self.desktop_frame, text="Version 12.0",
bg=self.wallpaper, fg="#d9efff",
font=("Segoe UI", 11)).place(relx=.5, rely=.48, anchor="center")
icons = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("⚙", "Settings", self.settings),
("💻", "Terminal", self.terminal),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
for i, item in enumerate(icons):
x = 22 + (i // 6) * 105
y = 20 + (i % 6) * 92
self.icon(*item, x=x, y=y)
# Pro Max utilities
pro_icons = [("⚡", "Action Center", self.action_center), ("🔎", "File Search Pro", self.file_search_pro), ("🎮", "Game Mode", self.game_mode_toggle), ("📋", "Clipboard", self.clipboard_manager), ("🧰", "Advanced Settings", self.advanced_settings)]
for j, item in enumerate(pro_icons):
self.icon(*item, x=22 + (j // 6) * 105, y=20 + ((j + len(icons)) % 6) * 92)
# taskbar
self.taskbar = tk.Frame(self.root, bg="#1f1f1f", height=48)
self.taskbar.pack(side="bottom", fill="x")
self.taskbar.pack_propagate(False)
tk.Button(self.taskbar, text="⊞", command=self.toggle_start,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 23)).pack(side="left", padx=6)
tk.Button(self.taskbar, text="🔍", command=self.search,
bg="#202020", fg="white", activebackground="#3b3b3b",
relief="flat", bd=0, font=("Segoe UI", 13)).pack(side="left", padx=3)
self.task_area = tk.Frame(self.taskbar, bg="#1f1f1f")
self.task_area.pack(side="left", fill="both", expand=True, padx=8)
# Windows 10 style pinned taskbar buttons
for text, cmd in [("▣", self.explorer), ("🌐", self.browser), ("🛍", self.app_center)]:
tk.Button(self.taskbar, text=text, command=cmd, bg="#1f1f1f", fg="white",
activebackground="#333333", relief="flat", bd=0,
font=("Segoe UI Emoji", 13)).pack(side="left", padx=2)
tk.Button(self.taskbar, text="⚡", command=self.action_center, bg="#1f1f1f", fg="white", activebackground="#333333", relief="flat", bd=0, font=("Segoe UI Emoji", 13)).pack(side="left", padx=3)
tray = tk.Frame(self.taskbar, bg="#202020")
tray.pack(side="right", fill="y")
tk.Button(tray, text="🔔", command=self.notification_center, bg="#202020", fg="white", relief="flat", bd=0).pack(side="left", padx=3)
tk.Button(tray, text="⌁ 🔊", command=self.quick_controls, bg="#202020", fg="white", relief="flat", bd=0,
font=("Segoe UI", 11)).pack(side="left", padx=4)
tk.Button(tray, text="⏻", command=self.power_menu_open, bg="#202020", fg="white",
activebackground="#3b3b3b", relief="flat", bd=0, font=("Segoe UI", 14)).pack(side="left", padx=4)
self.clock = tk.Label(tray, bg="#202020", fg="white",
font=("Segoe UI", 9), justify="right")
self.clock.pack(side="left", padx=10)
self.tick()
self.desktop_frame.bind("<Button-3>", self.context)
self.desktop_frame.bind("<Double-Button-1>", lambda e: self.close_start())
def icon(self, emoji, name, command, x, y):
f = tk.Frame(self.desktop_frame, bg=self.wallpaper, width=92, height=82)
f.place(x=x, y=y)
f.pack_propagate(False)
btn = tk.Button(f, text=emoji, command=command,
bg=self.wallpaper, fg="white", activebackground="#2b89c9",
relief="flat", bd=0, font=("Segoe UI Emoji", 25))
btn.pack(fill="x")
tk.Label(f, text=name, bg=self.wallpaper, fg="white",
font=("Segoe UI", 9), wraplength=88).pack()
self.desktop_icons.append(f)
def start_drag(e):
f._dx, f._dy = e.x, e.y
def drag(e):
nx=max(4, min(self.root.winfo_width()-100, f.winfo_x()+e.x-f._dx))
ny=max(4, min(self.root.winfo_height()-145, f.winfo_y()+e.y-f._dy))
f.place(x=nx, y=ny)
for w in (f, btn):
w.bind("<ButtonPress-1>", start_drag, add="+")
w.bind("<B1-Motion>", drag, add="+")
def quick_controls(self):
win=self.new_window("Quick Settings", "430x300")
tk.Label(win,text="⚡ Quick settings",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=20,pady=18)
for text,cmd in [("🎨 Personalization",self.personalize),("🔔 Notifications",self.notification_center),("⚙ Settings",self.settings),("ℹ About",self.system_info)]:
tk.Button(win,text=text,command=cmd,anchor="w",relief="flat",font=("Segoe UI",11)).pack(fill="x",padx=20,pady=4)
def tick(self):
if hasattr(self, "clock") and self.clock.winfo_exists():
self.clock.config(text=time.strftime("%H:%M\n%d/%m/%Y"))
self.root.after(1000, self.tick)
# ---------- Python OS 12 Pro Max system features ----------
def notify(self, title, text):
self.notifications.append((title, text, time.strftime("%H:%M")))
if len(self.notifications) > 30:
self.notifications = self.notifications[-30:]
def notification_center(self):
win = self.new_window("Notification Center", "520x520")
win.configure(bg="#f4f4f4")
tk.Label(win, text="🔔 Notifications", bg="#f4f4f4", fg="#222",
font=("Segoe UI", 20, "bold")).pack(anchor="w", padx=20, pady=18)
body = tk.Frame(win, bg="#f4f4f4")
body.pack(fill="both", expand=True, padx=14)
if not self.notifications:
tk.Label(body, text="You're all caught up.", bg="#f4f4f4", fg="#777",
font=("Segoe UI", 12)).pack(pady=50)
else:
for title, text, stamp in reversed(self.notifications):
card = tk.Frame(body, bg="white", bd=1, relief="solid")
card.pack(fill="x", pady=5)
tk.Label(card, text=f"{title} • {stamp}", bg="white", fg="#222",
font=("Segoe UI", 11, "bold")).pack(anchor="w", padx=12, pady=(9,2))
tk.Label(card, text=text, bg="white", fg="#555", wraplength=450,
justify="left").pack(anchor="w", padx=12, pady=(0,9))
tk.Button(win, text="Clear notifications", command=lambda:self.clear_notifications(win),
relief="flat").pack(anchor="e", padx=18, pady=12)
def clear_notifications(self, win=None):
self.notifications.clear()
if win and win.winfo_exists():
self.close_window(win)
self.notification_center()
def lock_screen(self):
self.close_start()
for w, _ in list(self.tasks):
try:
if w.winfo_exists(): w.withdraw()
except Exception: pass
self.clear()
self.root.configure(bg="#176aa5")
box = tk.Frame(self.root, bg="#176aa5")
box.pack(fill="both", expand=True)
tk.Label(box, text="⊞", fg="white", bg="#176aa5",
font=("Segoe UI", 80)).pack(pady=(125, 0))
tk.Label(box, text=self.username, fg="white", bg="#176aa5",
font=("Segoe UI", 24, "bold")).pack(pady=8)
tk.Label(box, text=time.strftime("%A, %d %B\n%H:%M"), fg="white", bg="#176aa5",
font=("Segoe UI", 18)).pack(pady=10)
b=tk.Button(box, text="🔓 Sign in", command=self.unlock_screen,
font=("Segoe UI", 12, "bold"), padx=30, pady=10)
b.pack(pady=25)
self.root.bind("<Return>", lambda e: self.unlock_screen())
def unlock_screen(self):
self.root.unbind("<Return>")
self.desktop()
self.notify("Python OS", "You signed in successfully.")
def personalize(self):
win=self.new_window("Personalization", "620x470")
tk.Label(win,text="🎨 Personalization",font=("Segoe UI",22,"bold")).pack(anchor="w",padx=20,pady=18)
tk.Label(win,text="Choose your desktop appearance.",fg="#666").pack(anchor="w",padx=20)
row=tk.Frame(win); row.pack(fill="x",padx=20,pady=20)
tk.Button(row,text="Choose color",command=self.choose_wallpaper).pack(side="left",padx=5)
tk.Button(row,text="Choose wallpaper image",command=self.choose_wallpaper_image).pack(side="left",padx=5)
tk.Button(row,text="Reset",command=lambda:self.reset_wallpaper()).pack(side="left",padx=5)
tk.Label(win,text="Keyboard shortcuts",font=("Segoe UI",14,"bold")).pack(anchor="w",padx=20,pady=(15,5))
tk.Label(win,text="Ctrl+Alt+D Show desktop\nCtrl+Alt+R Run\nCtrl+Alt+T Terminal\nCtrl+Alt+L Lock screen",justify="left").pack(anchor="w",padx=20)
def choose_wallpaper(self):
c=colorchooser.askcolor(title="Choose desktop color")
if c and c[1]:
self.wallpaper=c[1]
self.wallpaper_image=None
self.save_settings()
self.desktop()
self.notify("Personalization", "Desktop color changed.")
def choose_wallpaper_image(self):
path=filedialog.askopenfilename(title="Choose wallpaper",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if path:
try:
self.wallpaper_image=tk.PhotoImage(file=path)
self.wallpaper_path=path
self.wallpaper="#000000"
self.save_settings()
self.desktop()
self.notify("Personalization", "Wallpaper image applied.")
except Exception as e:
messagebox.showerror("Wallpaper", f"Could not load image.\n{e}")
def reset_wallpaper(self):
self.wallpaper="#0078d7"
self.wallpaper_image=None
self.wallpaper_path=""
self.save_settings(); self.desktop()
def system_info(self):
win=self.new_window("About Python OS", "560x390")
tk.Label(win,text="⊞ Python OS 12 Pro Max",font=("Segoe UI",24,"bold")).pack(pady=25)
info=f"Windows 10 Edition\n\nPython: {platform.python_version()}\nPlatform: {platform.platform()}\nArchitecture: {platform.machine()}\nUser: {self.username}"
tk.Label(win,text=info,justify="left",font=("Segoe UI",11)).pack(anchor="w",padx=35)
# ---------- windows ----------
def new_window(self, title, size="700x480"):
self.close_start()
win = tk.Toplevel(self.root)
win.title(title)
win.geometry(size)
win.minsize(350, 230)
win.protocol("WM_DELETE_WINDOW", lambda: self.close_window(win))
win.bind("<FocusIn>", lambda e: self.focus(win))
self.windows.append(win)
b = tk.Button(self.task_area, text=title[:18], command=lambda: self.focus(win),
bg="#303030", fg="white", activebackground="#505050",
relief="flat", bd=0, font=("Segoe UI", 9), padx=9)
b.pack(side="left", padx=2, pady=6)
self.tasks.append((win, b))
if hasattr(self, "window_desktops"):
self._window_shortcuts(win)
win.focus_force()
return win
def focus(self, win):
if win.winfo_exists():
win.deiconify()
win.lift()
win.focus_force()
def close_window(self, win):
for w, b in list(self.tasks):
if w is win:
b.destroy()
self.tasks.remove((w, b))
if win in self.windows:
self.windows.remove(win)
if win.winfo_exists():
win.destroy()
# ---------- start ----------
def toggle_start(self):
if self.start_open:
self.close_start()
return
self.start_open = True
self.start = tk.Frame(self.root, bg="#f4f4f4", width=620, height=620,
bd=1, relief="solid")
self.start.place(x=6, y=max(5, self.root.winfo_height()-665))
self.start.lift()
head = tk.Frame(self.start, bg="#0078d7", height=76)
head.pack(fill="x")
tk.Label(head, text=f"👤 {self.username}", bg="#0078d7", fg="white",
font=("Segoe UI", 14, "bold")).pack(side="left", padx=20, pady=22)
search = tk.Entry(self.start, font=("Segoe UI", 11))
search.pack(fill="x", padx=16, pady=12)
search.insert(0, "Search apps...")
search.bind("<FocusIn>", lambda e: search.delete(0, "end") if search.get()=="Search apps..." else None)
body = tk.Frame(self.start, bg="#f4f4f4")
body.pack(fill="both", expand=True)
apps = [
("📁", "File Explorer", self.explorer),
("📝", "Notepad", self.notepad),
("🧮", "Calculator", self.calculator),
("🌐", "Browser", self.browser),
("💻", "Terminal", self.terminal),
("⚙", "Settings", self.settings),
("🛍", "App Center", self.app_center),
("📦", "App Manager", self.app_manager),
("🗑", "Recycle Bin", self.recycle),
("▶", "Run", self.open_run),
("▣", "Task Manager", self.task_manager),
("🎨", "Personalization", self.personalize),
("🔔", "Notifications", self.notification_center),
("🎨", "Paint", self.paint),
("📅", "Calendar", self.calendar_app),
("📊", "System Monitor", self.system_monitor),
("🖼", "Image Viewer", self.image_viewer),
]
buttons = []
for ico, name, cmd in apps:
b = tk.Button(body, text=f"{ico} {name}", command=cmd,
anchor="w", bg="#f4f4f4", fg="#222",
activebackground="#dceefa", relief="flat",
font=("Segoe UI", 11), height=2)
b.pack(fill="x", padx=12, pady=1)
buttons.append((name.lower(), b))
def filter_apps(e=None):
q = search.get().lower()
for n, b in buttons:
b.pack_forget()
if q in n:
b.pack(fill="x", padx=12, pady=1)
search.bind("<KeyRelease>", filter_apps)
bottom = tk.Frame(self.start, bg="#e7e7e7", height=48)
bottom.pack(side="bottom", fill="x")
tk.Button(bottom, text="⚙ Settings", command=self.settings,
bg="#e7e7e7", relief="flat").pack(side="left", padx=12, pady=9)
tk.Button(bottom, text="🔒 Lock", command=self.lock_screen,
bg="#e7e7e7", relief="flat").pack(side="right", padx=4, pady=9)
tk.Button(bottom, text="⏻ Shut down", command=self.shutdown,
bg="#e7e7e7", relief="flat").pack(side="right", padx=12, pady=9)
def close_start(self):
if self.start_open and self.start.winfo_exists():
self.start.destroy()
self.start_open = False
# ---------- apps ----------
def explorer(self):
win = self.new_window("File Explorer 11", "980x600")
toolbar = tk.Frame(win, bg="#f2f2f2"); toolbar.pack(fill="x")
path = tk.StringVar(value=os.path.expanduser("~"))
history=[]; future=[]; clipboard={"path":None,"cut":False}
tk.Button(toolbar,text="←",command=lambda:go_back(),relief="flat").pack(side="left",padx=2)
tk.Button(toolbar,text="→",command=lambda:go_forward(),relief="flat").pack(side="left",padx=2)
tk.Button(toolbar,text="🏠",command=lambda:load(os.path.expanduser("~"),True),relief="flat").pack(side="left",padx=2)
ent=tk.Entry(toolbar,textvariable=path,font=("Segoe UI",10)); ent.pack(side="left",fill="x",expand=True,padx=5,pady=6)
tk.Button(toolbar,text="↻",command=lambda:load(path.get()),relief="flat").pack(side="left")
body=tk.PanedWindow(win,orient="horizontal",sashwidth=5); body.pack(fill="both",expand=True)
side=tk.Frame(body,bg="#f7f7f7",width=170); body.add(side,stretch="never")
box=ttk.Treeview(body,columns=("type","size"),show="tree headings"); box.heading("#0",text="Name"); box.heading("type",text="Type"); box.heading("size",text="Size"); box.column("type",width=100); box.column("size",width=110); body.add(box)
for label,pth in [("Desktop",os.path.join(os.path.expanduser("~"),"Desktop")),("Documents",os.path.join(os.path.expanduser("~"),"Documents")),("Downloads",os.path.join(os.path.expanduser("~"),"Downloads")),("Pictures",os.path.join(os.path.expanduser("~"),"Pictures")),("Home",os.path.expanduser("~"))]:
if os.path.isdir(pth): tk.Button(side,text=" "+label,anchor="w",relief="flat",bg="#f7f7f7",command=lambda q=pth:load(q,True)).pack(fill="x",pady=1)
bar=tk.Frame(win,bg="#eeeeee"); bar.pack(fill="x")
status=tk.Label(bar,text="Ready",anchor="w",bg="#eeeeee",fg="#555"); status.pack(side="left",padx=8,pady=5)
def selected():
ids=box.selection(); return os.path.join(path.get(),box.item(ids[0],"text")) if ids else None
def load(p,record=False):
try:
p=os.path.abspath(os.path.expanduser(p))
if not os.path.isdir(p): raise ValueError("Folder not found")
if record and path.get()!=p: history.append(path.get()); future.clear()
path.set(p); box.delete(*box.get_children())
for name in sorted(os.listdir(p),key=lambda x:(not os.path.isdir(os.path.join(p,x)),x.lower())):
full=os.path.join(p,name); isdir=os.path.isdir(full); size="—" if isdir else str(os.path.getsize(full))+" B"
box.insert("","end",text=name,values=("Folder" if isdir else "File",size))
status.config(text=f"{len(box.get_children())} items • {p}")
except Exception as e: messagebox.showerror("File Explorer",str(e),parent=win)
def go_back():
if history: future.append(path.get()); load(history.pop(),False)
def go_forward():
if future: history.append(path.get()); load(future.pop(),False)
def open_item(e=None):
p=selected()
if not p:return
if os.path.isdir(p): load(p,True)
else:
try:
if platform.system()=="Windows": os.startfile(p)
elif platform.system()=="Darwin": subprocess.Popen(["open",p])
else: subprocess.Popen(["xdg-open",p])
except Exception as ex: messagebox.showerror("Open",str(ex),parent=win)
def new_folder():
name= simpledialog.askstring("New Folder","Folder name:",parent=win) if 'simpledialog' in globals() else None
if name:
try: os.makedirs(os.path.join(path.get(),name),exist_ok=False); load(path.get())
except Exception as e: messagebox.showerror("New Folder",str(e),parent=win)
def delete_item():
p=selected()
if not p:return
if messagebox.askyesno("Delete",f"Delete {os.path.basename(p)}?",parent=win):
try: shutil.rmtree(p) if os.path.isdir(p) else os.remove(p); load(path.get())
except Exception as e: messagebox.showerror("Delete",str(e),parent=win)
def rename_item():
p=selected()
if not p:return
name=simpledialog.askstring("Rename","New name:",initialvalue=os.path.basename(p),parent=win) if 'simpledialog' in globals() else None
if name:
try: os.rename(p,os.path.join(path.get(),name)); load(path.get())
except Exception as e: messagebox.showerror("Rename",str(e),parent=win)
def copy_item(cut=False):
p=selected()
if p: clipboard.update(path=p,cut=cut); status.config(text=("Cut: " if cut else "Copied: ")+os.path.basename(p))
def paste_item():
p=clipboard.get("path")
if not p:return
try:
dest=os.path.join(path.get(),os.path.basename(p));
if clipboard.get("cut"): shutil.move(p,dest); clipboard["path"]=None
elif os.path.isdir(p): shutil.copytree(p,dest)
else: shutil.copy2(p,dest)
load(path.get())
except Exception as e: messagebox.showerror("Paste",str(e),parent=win)
for text,cmd in [("+ Folder",new_folder),("Rename",rename_item),("Delete",delete_item),("Copy",lambda:copy_item(False)),("Cut",lambda:copy_item(True)),("Paste",paste_item)]: tk.Button(toolbar,text=text,command=cmd,relief="flat").pack(side="left",padx=2)
ent.bind("<Return>",lambda e:load(path.get(),True)); box.bind("<Double-1>",open_item)
load(path.get())
def notepad(self):
win = self.new_window("Notepad", "800x560")
bar = tk.Frame(win, bg="#eeeeee"); bar.pack(fill="x")
text = tk.Text(win, font=("Consolas", 12), undo=True, wrap="word")
text.pack(fill="both", expand=True)
def new(): text.delete("1.0","end")
def openf():
p=filedialog.askopenfilename(parent=win,filetypes=[("Text","*.txt"),("All","*.*")])
if p:
try:
text.delete("1.0","end"); text.insert("1.0",open(p,encoding="utf-8").read())
except Exception as e: messagebox.showerror("Notepad",str(e),parent=win)
def save():
p=filedialog.asksaveasfilename(parent=win,defaultextension=".txt",
filetypes=[("Text","*.txt"),("All","*.*")])
if p: open(p,"w",encoding="utf-8").write(text.get("1.0","end-1c"))
for n,c in [("New",new),("Open",openf),("Save",save)]:
tk.Button(bar,text=n,command=c,relief="flat").pack(side="left",padx=4,pady=4)
def calculator(self):
win=self.new_window("Calculator","380x520")
exp=tk.StringVar()
tk.Entry(win,textvariable=exp,justify="right",font=("Segoe UI",24),bd=0).pack(fill="x",padx=12,pady=15,ipady=8)
grid=tk.Frame(win); grid.pack(fill="both",expand=True,padx=8,pady=8)
keys=[["C","(",")","/"],["7","8","9","*"],["4","5","6","-"],["1","2","3","+"],["0",".","⌫","="]]
def press(k):
if k=="C": exp.set("")
elif k=="⌫": exp.set(exp.get()[:-1])
elif k=="=":
try:
if any(c not in "0123456789.+-*/() " for c in exp.get()): raise ValueError()
exp.set(str(eval(exp.get(),{"__builtins__":{}},{})))
except: exp.set("Error")
else: exp.set(exp.get()+k)
for r,row in enumerate(keys):
for c,k in enumerate(row):
tk.Button(grid,text=k,command=lambda x=k:press(x),
font=("Segoe UI",13),relief="flat").grid(row=r,column=c,sticky="nsew",padx=2,pady=2)
for r in range(5): grid.rowconfigure(r,weight=1)
for c in range(4): grid.columnconfigure(c,weight=1)
def browser(self):
win=self.new_window("Python Browser","760x520")
tk.Label(win,text="🌐 Python Browser",font=("Segoe UI",20,"bold")).pack(pady=18)
tk.Label(win,text="This lightweight browser opens web pages in your default browser.",
fg="#666").pack()
url=tk.Entry(win,font=("Segoe UI",12))
url.pack(fill="x",padx=35,pady=15)
url.insert(0,"https://[Log in to view URL]")
def go():
u=url.get().strip()
if not u.startswith(("http://","https://")): u="https://"+u
try:
import webbrowser; webbrowser.open(u)
except Exception as e: messagebox.showerror("Browser",str(e),parent=win)
tk.Button(win,text="Open website",command=go,width=18).pack()
def settings(self):
win=self.new_window("Settings","700x520")
tk.Label(win,text="Settings",font=("Segoe UI",26,"bold")).pack(anchor="w",padx=25,pady=20)
tk.Label(win,text="Personalization",font=("Segoe UI",13,"bold")).pack(anchor="w",padx=25,pady=5)
colors=[("Windows Blue","#0878c9"),("Dark Blue","#123b63"),("Green","#197a3a"),
("Purple","#663399"),("Dark","#222222")]
def setbg(c):
self.wallpaper=c
self.desktop_frame.config(bg=c)
for w in self.desktop_frame.winfo_children():
try: w.config(bg=c)
except: pass
self.save_settings()
for n,c in colors:
tk.Button(win,text=n,command=lambda c=c:setbg(c),width=24,anchor="w").pack(anchor="w",padx=25,pady=3)
tk.Button(win,text="Choose custom color",
command=lambda:(lambda c:c and setbg(c))(colorchooser.askcolor(parent=win)[1])).pack(anchor="w",padx=25,pady=8)
tk.Label(win,text=f"Python {platform.python_version()} • {platform.system()}",
fg="#777").pack(anchor="w",padx=25,pady=18)
def terminal(self):
win=self.new_window("Terminal","800x500")
out=tk.Text(win,bg="#0c0c0c",fg="#eee",insertbackground="white",font=("Consolas",11))
out.pack(fill="both",expand=True)
out.insert("end","Python OS Terminal 3.0\nType 'help' for commands.\n\n> ")
ent=tk.Entry(win,bg="#0c0c0c",fg="white",insertbackground="white",font=("Consolas",11))
ent.pack(fill="x")
def write(s): out.insert("end",s+"\n"); out.see("end")
def run(e=None):
cmd=ent.get().strip(); ent.delete(0,"end")
if not cmd:return
out.insert("end",cmd+"\n")
if cmd=="help": write("help, clear, time, date, system, pwd, dir, echo <text>, python")
elif cmd=="clear": out.delete("1.0","end")
elif cmd=="time": write(time.strftime("%H:%M:%S"))
elif cmd=="date": write(time.strftime("%Y-%m-%d"))
elif cmd=="system": write(f"{platform.system()} {platform.release()} | Python {platform.python_version()}")
elif cmd=="pwd": write(os.getcwd())
elif cmd=="dir":
try: write("\n".join(os.listdir()))
except Exception as e: write("Error: "+str(e))
elif cmd=="python": write("Python "+platform.python_version())
elif cmd.startswith("echo "): write(cmd[5:])
else: write("Unknown command. Type 'help'.")
out.insert("end","\n> "); out.see("end")
ent.bind("<Return>",run); ent.focus()
def search(self):
win=self.new_window("Search","600x400")
tk.Label(win,text="Search Python OS",font=("Segoe UI",22,"bold")).pack(pady=20)
ent=tk.Entry(win,font=("Segoe UI",13)); ent.pack(fill="x",padx=30)
box=tk.Listbox(win,font=("Segoe UI",11)); box.pack(fill="both",expand=True,padx=30,pady=15)
apps=[("File Explorer",self.explorer),("Notepad",self.notepad),("Calculator",self.calculator),
("Browser",self.browser),("Settings",self.settings),("App Center",self.app_center),("App Manager",self.app_manager),
("Terminal",self.terminal),("Recycle Bin",self.recycle),("Paint",self.paint),("Calendar",self.calendar_app),("System Monitor",self.system_monitor),("Image Viewer",self.image_viewer)]
def do(e=None):
q=ent.get().lower(); box.delete(0,"end")
for n,_ in apps:
if q in n.lower(): box.insert("end",n)
def launch(e=None):
s=box.curselection()
if not s:return
for n,c in apps:
if n==box.get(s[0]): c(); break
ent.bind("<KeyRelease>",do); box.bind("<Double-Button-1>",launch)
def recycle(self):
win=self.new_window("Recycle Bin","500x330")
tk.Label(win,text="🗑",font=("Segoe UI Emoji",55)).pack(pady=30)
tk.Label(win,text="Recycle Bin is empty",font=("Segoe UI",13)).pack()
tk.Button(win,text="Close",command=lambda:self.close_window(win)).pack(pady=25)
# ---------- Python OS App System ----------
def installed_apps(self):
result = []
for folder in sorted(os.listdir(self.apps_data)):
p = os.path.join(self.apps_data, folder)
mf = os.path.join(p, "app.json")
if os.path.isdir(p) and os.path.isfile(mf):
try:
with open(mf, encoding="utf-8") as f:
m = json.load(f)
if m.get("id") and m.get("name"):
result.append((p, m))
except Exception:
pass
return result
def app_manager(self):
win = self.new_window("App Manager", "820x560")
tk.Label(win, text="📦 Python OS App Manager",
font=("Segoe UI", 23, "bold")).pack(anchor="w", padx=25, pady=(20, 3))
tk.Label(win, text="Install, launch and uninstall .pyapp applications",
fg="#666").pack(anchor="w", padx=25)
bar = tk.Frame(win); bar.pack(fill="x", padx=20, pady=12)
box = tk.Listbox(win, font=("Segoe UI", 11), activestyle="none")
box.pack(fill="both", expand=True, padx=20, pady=5)
apps = []
def refresh():
nonlocal apps
apps = self.installed_apps()
box.delete(0, "end")
if not apps:
box.insert("end", " No applications installed")
for folder, m in apps:
box.insert("end", f" {m['name']} — v{m.get('version','1.0')} — {m.get('description','')}")
def selected():
s = box.curselection()
return apps[s[0]] if s and s[0] < len(apps) else None
def launch():
item = selected()
if item:
self.launch_installed_app(*item)
def uninstall():
item = selected()
if not item: return
folder, m = item
if messagebox.askyesno("Uninstall", f"Uninstall {m['name']}?", parent=win):
try:
shutil.rmtree(folder)
refresh()
except Exception as e:
messagebox.showerror("Uninstall", str(e), parent=win)
tk.Button(bar, text="📥 Install .pyapp", command=self.install_app, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="▶ Launch", command=launch, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="🗑 Uninstall", command=uninstall, relief="flat").pack(side="left", padx=4)
tk.Button(bar, text="↻ Refresh", command=refresh, relief="flat").pack(side="right", padx=4)
box.bind("<Double-Button-1>", lambda e: launch())
refresh()
def install_app(self):
p = filedialog.askopenfilename(
title="Install Python OS App",
filetypes=[("Python OS App", "*.pyapp"), ("ZIP package", "*.zip"), ("All files", "*.*")])
if not p: return
try:
if not zipfile.is_zipfile(p):
raise ValueError("The selected file is not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id", "name", "version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
messagebox.showinfo("Python OS", f"{manifest['name']} v{manifest['version']} installed successfully!", parent=self.root)
except Exception as e:
messagebox.showerror("Installation failed", str(e), parent=self.root)
def launch_installed_app(self, folder, manifest):
main = os.path.join(folder, "main.py")
if not os.path.isfile(main):
messagebox.showerror("App", "main.py was not found.", parent=self.root)
return
try:
namespace = {"__name__": "__main__", "__file__": main,
"PYTHON_OS_APP": self, "APP_DIR": folder}
with open(main, encoding="utf-8") as f:
source = f.read()
exec(compile(source, main, "exec"), namespace, namespace)
except Exception as e:
messagebox.showerror(f"App error: {manifest.get('name','App')}", str(e), parent=self.root)
def create_example_app(self):
p = filedialog.asksaveasfilename(
title="Create example Python OS App", defaultextension=".pyapp",
filetypes=[("Python OS App", "*.pyapp")], initialfile="HelloPythonOS.pyapp")
if not p: return
manifest = {
"id": "hello-python-os", "name": "Hello Python OS", "version": "1.0",
"description": "A sample Python OS application"
}
main = """import tkinter as tk
from tkinter import simpledialog
win = tk.Toplevel(PYTHON_OS_APP.root)
win.title("Hello Python OS")
win.geometry("430x250")
tk.Label(win, text="🎉 Hello from a Python OS App!",
font=("Segoe UI", 17, "bold")).pack(pady=50)
tk.Label(win, text="This app was installed from a .pyapp package.",
fg="#666").pack()
tk.Button(win, text="Close", command=win.destroy).pack(pady=25)
"""
try:
with zipfile.ZipFile(p, "w", zipfile.ZIP_DEFLATED) as z:
z.writestr("app.json", json.dumps(manifest, indent=2, ensure_ascii=False))
z.writestr("main.py", main)
messagebox.showinfo("Python OS", "Example .pyapp created.", parent=self.root)
except Exception as e:
messagebox.showerror("Create app", str(e), parent=self.root)
def app_store(self):
win = self.new_window("Python OS App Store", "720x470")
tk.Label(win, text="🛍 Python OS App Store",
font=("Segoe UI", 24, "bold")).pack(pady=(25, 5))
tk.Label(win, text="Local application installer",
fg="#666").pack()
tk.Label(win, text="Choose a .pyapp file to install it on Python OS.",
font=("Segoe UI", 11)).pack(pady=25)
tk.Button(win, text="📥 Install .pyapp", command=self.install_app,
width=25, pady=8).pack(pady=6)
tk.Button(win, text="🧪 Create example .pyapp",
command=self.create_example_app, width=25, pady=8).pack(pady=6)
tk.Button(win, text="📦 App Manager",
command=self.app_manager, width=25, pady=8).pack(pady=6)
tk.Label(win, text="Package = ZIP renamed to .pyapp, containing app.json + main.py",
fg="#777", font=("Segoe UI", 9)).pack(pady=25)
# ---------- Microsoft-style App Center ----------
def app_catalog(self):
"""Built-in catalog. A catalog.json can override/extend it."""
built_in = [
{"id":"hello-python-os","name":"Hello Python OS","version":"1.0",
"category":"Demo","description":"A tiny example app for Python OS.",
"type":"builtin"},
{"id":"calculator","name":"Calculator","version":"1.0",
"category":"Tools","description":"Built-in Python OS calculator.",
"type":"builtin"},
{"id":"notepad","name":"Notepad","version":"1.0",
"category":"Productivity","description":"Simple text editor.",
"type":"builtin"},
{"id":"terminal","name":"Terminal","version":"1.0",
"category":"System","description":"Python OS command terminal.",
"type":"builtin"},
]
try:
with open(self.catalog_file, "r", encoding="utf-8") as f:
external = json.load(f)
if isinstance(external, list):
by_id = {x["id"]:x for x in built_in if isinstance(x,dict) and x.get("id")}
for x in external:
if isinstance(x,dict) and x.get("id") and x.get("name"):
by_id[x["id"]] = x
return list(by_id.values())
except Exception:
pass
return built_in
def app_center(self):
win = self.new_window("Microsoft-style App Center", "950x650")
win.minsize(720, 480)
header = tk.Frame(win, bg="#176aa5", height=90)
header.pack(fill="x")
tk.Label(header, text="🛍 Python OS App Center",
bg="#0078d7", fg="white",
font=("Segoe UI", 22, "bold")).pack(side="left", padx=24, pady=22)
search_var = tk.StringVar()
search = tk.Entry(header, textvariable=search_var,
font=("Segoe UI", 11), width=30)
search.pack(side="right", padx=20, pady=27)
search.insert(0, "Search apps...")
body = tk.Frame(win, bg="#f3f3f3")
body.pack(fill="both", expand=True)
categories = tk.Frame(body, bg="#e6e6e6", width=145)
categories.pack(side="left", fill="y")
categories.pack_propagate(False)
content = tk.Frame(body, bg="#f3f3f3")
content.pack(side="left", fill="both", expand=True)
canvas = tk.Canvas(content, bg="#f3f3f3", highlightthickness=0)
scroll = tk.Scrollbar(content, orient="vertical", command=canvas.yview)
cards = tk.Frame(canvas, bg="#f3f3f3")
canvas.create_window((0,0), window=cards, anchor="nw")
canvas.configure(yscrollcommand=scroll.set)
canvas.pack(side="left", fill="both", expand=True)
scroll.pack(side="right", fill="y")
catalog = self.app_catalog()
current_category = ["All"]
def installed_ids():
return {m.get("id") for _, m in self.installed_apps()}
def launch_builtin(app_id):
mapping = {
"calculator": self.calculator,
"notepad": self.notepad,
"terminal": self.terminal,
"hello-python-os": self.create_example_app,
}
if app_id in mapping:
mapping[app_id]()
def install_catalog_item(app):
if app.get("type") == "builtin":
if app["id"] in installed_ids():
launch_builtin(app["id"])
return
# Built-ins are represented by creating a real .pyapp package.
if app["id"] == "hello-python-os":
self.create_example_app()
return
messagebox.showinfo(
"Python OS", "This built-in app is already part of Python OS.",
parent=win)
return
url = app.get("url")
if not url:
messagebox.showwarning(
"Python OS", "This catalog entry has no download URL.", parent=win)
return
self.download_and_install(url, app.get("name","App"), win)
def render():
for w in cards.winfo_children():
w.destroy()
q = search_var.get().lower().strip()
installed = installed_ids()
shown = 0
for app in catalog:
cat = app.get("category","Other")
if current_category[0] != "All" and cat != current_category[0]:
continue
if q and q not in (app.get("name","")+" "+app.get("description","")).lower():
continue
card = tk.Frame(cards, bg="white", bd=1, relief="solid",
padx=14, pady=10)
card.pack(fill="x", padx=18, pady=8)
shown += 1
icon = app.get("icon","📦")
tk.Label(card, text=icon, bg="white",
font=("Segoe UI Emoji", 30)).pack(side="left", padx=8)
info = tk.Frame(card, bg="white")
info.pack(side="left", fill="x", expand=True)
tk.Label(info, text=app.get("name","Unnamed"),
bg="white", fg="#222",
font=("Segoe UI", 13, "bold")).pack(anchor="w")
tk.Label(info, text=f"v{app.get('version','1.0')} • {cat}",
bg="white", fg="#777").pack(anchor="w")
tk.Label(info, text=app.get("description",""),
bg="white", fg="#555", wraplength=470,
justify="left").pack(anchor="w", pady=(4,0))
aid = app.get("id")
if aid in installed:
button_text = "▶ Open"
elif app.get("type") == "builtin" and aid != "hello-python-os":
button_text = "Included"
else:
button_text = "📥 Install"
tk.Button(card, text=button_text,
command=lambda a=app: install_catalog_item(a),
width=12, relief="flat",
bg="#0878c9" if button_text != "Included" else "#ddd",
fg="white" if button_text != "Included" else "#555").pack(
side="right", padx=10)
if shown == 0:
tk.Label(cards, text="No apps found.",
bg="#f3f3f3", fg="#777",
font=("Segoe UI", 12)).pack(pady=40)
cards.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"))
cats = ["All"] + sorted({a.get("category","Other") for a in catalog})
for cat in cats:
tk.Button(categories, text=cat, command=lambda c=cat:(
current_category.__setitem__(0,c), render()),
anchor="w", relief="flat", bg="#e6e6e6",
font=("Segoe UI", 10)).pack(fill="x", padx=8, pady=3)
search_var.trace_add("write", lambda *args: render())
footer = tk.Frame(win, bg="#202020", height=45)
footer.pack(fill="x")
tk.Button(footer, text="📦 App Manager", command=self.app_manager,
relief="flat").pack(side="left", padx=10, pady=8)
tk.Label(footer, text="Python OS 12 Pro Max • Windows 10 Edition",
bg="#202020", fg="white").pack(side="right", padx=15)
render()
def download_and_install(self, url, app_name, parent):
"""Download a .pyapp URL and pass it through the normal installer."""
def worker():
temp_path = os.path.join(
self.apps_dir, "download_" + next(tempfile._get_candidate_names()) + ".pyapp")
try:
urllib.request.urlretrieve(url, temp_path)
# Reuse installation logic by directly installing this downloaded file.
self.install_app_file(temp_path, parent)
except Exception as e:
self.root.after(0, lambda: messagebox.showerror(
"Download failed", f"{app_name}\n\n{e}", parent=parent))
finally:
try:
if os.path.exists(temp_path):
os.remove(temp_path)
except Exception:
pass
threading.Thread(target=worker, daemon=True).start()
messagebox.showinfo(
"Python OS", f"Downloading {app_name} in the background...",
parent=parent)
def install_app_file(self, p, parent=None):
try:
if not zipfile.is_zipfile(p):
raise ValueError("Not a valid .pyapp ZIP package.")
with zipfile.ZipFile(p) as z:
names = z.namelist()
if "app.json" not in names or "main.py" not in names:
raise ValueError("A .pyapp must contain app.json and main.py.")
manifest = json.loads(z.read("app.json").decode("utf-8"))
for key in ("id","name","version"):
if not manifest.get(key):
raise ValueError(f"app.json is missing '{key}'.")
app_id = str(manifest["id"])
if not re.fullmatch(r"[A-Za-z0-9._-]+", app_id):
raise ValueError("Invalid app id.")
destination = os.path.join(self.apps_data, app_id)
temp = tempfile.mkdtemp(prefix="install_", dir=self.apps_dir)
try:
base = os.path.abspath(temp)
for member in z.infolist():
target = os.path.abspath(os.path.join(temp, member.filename))
if not (target == base or target.startswith(base + os.sep)):
raise ValueError("Unsafe package path.")
z.extractall(temp)
if os.path.exists(destination):
shutil.rmtree(destination)
shutil.move(temp, destination)
temp = None
finally:
if temp and os.path.exists(temp):
shutil.rmtree(temp)
target = parent or self.root
self.root.after(0, lambda: messagebox.showinfo(
"Python OS", f"{manifest['name']} v{manifest['version']} installed!",
parent=target))
except Exception as e:
target = parent or self.root
self.root.after(0, lambda: messagebox.showerror(
"Installation failed", str(e), parent=target))
# ---------- context / shutdown ----------
# ---------- Python OS 12 Pro Max Windows-10 style features ----------
def show_desktop(self):
for w, _ in list(self.tasks):
try:
if w.winfo_exists():
w.withdraw()
except Exception:
pass
def minimize_all(self):
self.show_desktop()
def open_run(self):
win = self.new_window("Run", "500x190")
tk.Label(win, text="Run", font=("Segoe UI", 18, "bold")).pack(anchor="w", padx=20, pady=(18, 5))
tk.Label(win, text="Type the name of a program or Python OS command.").pack(anchor="w", padx=20)
ent = tk.Entry(win, font=("Segoe UI", 11))
ent.pack(fill="x", padx=20, pady=12)
def go(e=None):
q = ent.get().strip()
if not q:
return
commands = {
"explorer": self.explorer, "notepad": self.notepad,
"calc": self.calculator, "calculator": self.calculator,
"terminal": self.terminal, "cmd": self.terminal,
"settings": self.settings, "store": self.app_center,
"app center": self.app_center
}
if q.lower() in commands:
commands[q.lower()]()
self.close_window(win)
else:
try:
if platform.system() == "Windows":
subprocess.Popen(q, shell=True)
else:
subprocess.Popen(q, shell=True)
self.close_window(win)
except Exception as ex:
messagebox.showerror("Run", str(ex), parent=win)
tk.Button(win, text="OK", command=go, width=10).pack(side="right", padx=10)
tk.Button(win, text="Cancel", command=lambda:self.close_window(win), width=10).pack(side="right")
ent.bind("<Return>", go)
ent.focus_force()
def alt_tab(self, event=None):
live=[]
for w, _ in list(self.tasks):
try:
if w.winfo_exists() and w.state() != "withdrawn":
live.append(w)
except Exception:
pass
if not live:
return "break"
self.alt_tab_index=(self.alt_tab_index+1) % len(live)
self.focus(live[self.alt_tab_index])
return "break"
def power_menu_open(self):
if self.power_menu and self.power_menu.winfo_exists():
self.power_menu.destroy(); self.power_menu=None; return
m=tk.Toplevel(self.root)
self.power_menu=m
m.overrideredirect(True)
m.configure(bg="#f4f4f4", bd=1, relief="solid")
w=290; h=270
x=self.root.winfo_rootx()+self.root.winfo_width()-w-12
y=self.root.winfo_rooty()+self.root.winfo_height()-h-62
m.geometry(f"{w}x{h}+{max(0,x)}+{max(0,y)}")
tk.Label(m,text="Power",bg="#f4f4f4",fg="#222",font=("Segoe UI",17,"bold")).pack(anchor="w",padx=18,pady=(16,8))
tk.Label(m,text="What do you want to do?",bg="#f4f4f4",fg="#666").pack(anchor="w",padx=18,pady=(0,10))
def act(fn):
if m.winfo_exists(): m.destroy()
self.power_menu=None
fn()
for text,fn in [("⏾ Sleep",self.sleep_os),("↻ Restart",self.restart_os),("🔒 Lock",self.lock_screen),("⏻ Shut down",self.shutdown)]:
tk.Button(m,text=text,command=lambda f=fn:act(f),anchor="w",bg="white",fg="#222",
activebackground="#dceefa",relief="flat",font=("Segoe UI",11),height=2).pack(fill="x",padx=12,pady=2)
m.bind("<Escape>",lambda e:m.destroy())
m.focus_force()
def sleep_os(self):
self.show_desktop()
self.notify("Power", "Python OS is in sleep mode.")
def restart_os(self):
self.close_start()
self.clear()
self.windows=[]; self.tasks=[]
self.boot()
def taskbar_menu(self, event):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="Toolbars")
m.add_separator()
m.add_command(label="Task Manager", command=self.task_manager)
m.add_command(label="Show the desktop", command=self.show_desktop)
m.add_separator()
m.add_command(label="Taskbar settings", command=self.settings)
m.tk_popup(event.x_root, event.y_root)
def task_manager(self):
win = self.new_window("Task Manager", "650x430")
tk.Label(win, text="Task Manager", font=("Segoe UI", 22, "bold")).pack(anchor="w", padx=20, pady=18)
box = tk.Listbox(win, font=("Consolas", 10))
box.pack(fill="both", expand=True, padx=20, pady=5)
def refresh():
box.delete(0, "end")
box.insert("end", "Python OS processes")
box.insert("end", "-" * 55)
for w, b in self.tasks:
try:
if w.winfo_exists():
box.insert("end", f"APP {w.title()}")
except Exception:
pass
box.insert("end", "")
box.insert("end", f"Open windows: {len(self.tasks)}")
box.insert("end", f"Python: {platform.python_version()}")
tk.Button(win, text="↻ Refresh", command=refresh).pack(anchor="e", padx=20, pady=8)
refresh()
def context(self, e):
m = tk.Menu(self.root, tearoff=False)
m.add_command(label="View")
m.add_command(label="Sort by")
m.add_separator()
m.add_command(label="Refresh", command=lambda:self.desktop_frame.update())
m.add_separator()
m.add_command(label="Open File Explorer", command=self.explorer)
m.add_command(label="Open Terminal", command=self.terminal)
m.add_command(label="Personalize", command=self.personalize)
m.add_command(label="About Python OS", command=self.system_info)
m.add_separator()
m.add_command(label="Show desktop", command=self.show_desktop)
m.add_command(label="Shut Down", command=self.shutdown)
m.tk_popup(e.x_root, e.y_root)
def shutdown(self):
if messagebox.askyesno("Python OS","Shut down Python OS?",parent=self.root):
self.root.configure(bg="#080808")
for w in self.root.winfo_children():
w.destroy()
tk.Label(self.root,text="⏻",fg="white",bg="#080808",font=("Segoe UI",70)).pack(pady=(220,10))
tk.Label(self.root,text="Python OS is shutting down...",fg="white",bg="#080808",font=("Segoe UI",16)).pack()
self.root.after(900,self.root.destroy)
# ---------- Python OS 12 Pro Max features ----------
def _window_shortcuts(self, win):
win.bind("<Control-w>", lambda e: self.close_window(win))
win.bind("<Control-m>", lambda e: win.iconify())
win.bind("<Control-Shift-m>", lambda e: self._toggle_max(win))
win.bind("<Alt-Left>", lambda e: self._snap(win, "left"))
win.bind("<Alt-Right>", lambda e: self._snap(win, "right"))
win.bind("<Alt-Up>", lambda e: self._snap(win, "max"))
win.bind("<Alt-Down>", lambda e: self._snap(win, "restore"))
self.window_desktops[win] = self.virtual_desktop
def _toggle_max(self, win):
try: win.state("normal" if win.state()=="zoomed" else "zoomed")
except Exception: pass
def _snap(self, win, side):
sw=max(800,self.root.winfo_width()); sh=max(500,self.root.winfo_height()-48)
if side=="left": win.geometry(f"{sw//2}x{sh}+0+0")
elif side=="right": win.geometry(f"{sw//2}x{sh}+{sw//2}+0")
elif side=="max": win.geometry(f"{sw}x{sh}+0+0")
else: win.geometry("760x500+80+60")
def virtual_desktops(self):
win=self.new_window("Virtual Desktops","500x350")
tk.Label(win,text="🖥 Virtual Desktops",font=("Segoe UI",22,"bold")).pack(pady=18)
tk.Label(win,text="Switch workspace without closing your apps.",fg="#666").pack(pady=(0,15))
row=tk.Frame(win); row.pack(pady=10)
for i in range(1,self.desktop_count+1):
tk.Button(row,text=f"Desktop {i}",width=12,command=lambda n=i:self.switch_desktop(n,win)).pack(side="left",padx=5)
tk.Label(win,text=f"Current desktop: {self.virtual_desktop}",font=("Segoe UI",11,"bold")).pack(pady=15)
tk.Button(win,text="+ New desktop",command=lambda:self._add_virtual_desktop(win)).pack()
def _add_virtual_desktop(self, win):
if self.desktop_count<6: self.desktop_count+=1
self.close_window(win); self.virtual_desktops()
def switch_desktop(self,n,dialog=None):
self.virtual_desktop=n
for w in list(self.windows):
if not w.winfo_exists(): continue
if self.window_desktops.get(w,1)==n: w.deiconify()
else: w.withdraw()
if dialog and dialog.winfo_exists(): self.close_window(dialog)
self.notify("Virtual Desktop",f"Switched to Desktop {n}.")
def paint(self):
win=self.new_window("Paint","820x600")
bar=tk.Frame(win,bg="#eeeeee"); bar.pack(fill="x")
color=tk.StringVar(value="#111111"); size=tk.IntVar(value=4)
canvas=tk.Canvas(win,bg="white",cursor="crosshair",highlightthickness=0); canvas.pack(fill="both",expand=True)
last=[None,None]
def pick():
c=colorchooser.askcolor(parent=win)[1]
if c: color.set(c)
def down(e): last[:]=[e.x,e.y]
def move(e):
if last[0] is not None:
canvas.create_line(last[0],last[1],e.x,e.y,fill=color.get(),width=size.get(),capstyle="round")
last[:]=[e.x,e.y]
def up(e): last[:]=[None,None]
tk.Button(bar,text="🎨 Color",command=pick,relief="flat").pack(side="left",padx=4,pady=4)
tk.Label(bar,text="Size").pack(side="left")
tk.Scale(bar,from_=1,to=30,variable=size,orient="horizontal",length=120).pack(side="left")
tk.Button(bar,text="New",command=lambda:canvas.delete("all"),relief="flat").pack(side="left",padx=4)
canvas.bind("<ButtonPress-1>",down); canvas.bind("<B1-Motion>",move); canvas.bind("<ButtonRelease-1>",up)
def calendar_app(self):
import calendar as cal
from datetime import datetime
now=datetime.now(); win=self.new_window("Calendar","620x500")
head=tk.Frame(win); head.pack(fill="x",pady=12)
year=tk.IntVar(value=now.year); month=tk.IntVar(value=now.month)
view=tk.Text(win,font=("Consolas",13),height=15,bg="white",relief="flat"); view.pack(fill="both",expand=True,padx=20)
def draw(): view.delete("1.0","end"); view.insert("end",cal.month(year.get(),month.get()))
def prev():
if month.get()==1: month.set(12); year.set(year.get()-1)
else: month.set(month.get()-1)
draw()
def nxt():
if month.get()==12: month.set(1); year.set(year.get()+1)
else: month.set(month.get()+1)
draw()
tk.Button(head,text="◀",command=prev).pack(side="left",padx=20); tk.Label(head,textvariable=month,font=("Segoe UI",14,"bold")).pack(side="left")
tk.Label(head,textvariable=year,font=("Segoe UI",14,"bold")).pack(side="left",padx=8); tk.Button(head,text="▶",command=nxt).pack(side="left")
draw()
def image_viewer(self):
p=filedialog.askopenfilename(title="Open image",filetypes=[("Images","*.png *.gif *.ppm *.pgm"),("All files","*.*")])
if not p:return
try:
img=tk.PhotoImage(file=p); win=self.new_window("Image Viewer","850x650")
tk.Label(win,text=os.path.basename(p),font=("Segoe UI",14,"bold")).pack(pady=8)
holder=tk.Label(win,image=img,bg="#222"); holder.image=img; holder.pack(fill="both",expand=True,padx=10,pady=10)
except Exception as e: messagebox.showerror("Image Viewer",str(e),parent=self.root)
def system_monitor(self):
win=self.new_window("System Monitor","700x480")
tree=ttk.Treeview(win,columns=("value",),show="headings")
tree.heading("value",text="System information"); tree.column("value",width=600); tree.pack(fill="both",expand=True,padx=15,pady=15)
def refresh():
if not win.winfo_exists(): return
for x in tree.get_children(): tree.delete(x)
rows=[("Python",platform.python_version()),("Platform",platform.platform()),("Architecture",platform.machine()),("Processor",platform.processor() or "Unknown"),("Working directory",os.getcwd()),("Open windows",sum(1 for w in self.windows if w.winfo_exists())),("Virtual desktop",self.virtual_desktop),("Notifications",len(self.notifications))]
for k,v in rows: tree.insert("","end",values=(f"{k}: {v}",))
win.after(1500,refresh)
refresh()
def user_profile(self):
win=self.new_window("User Profile","480x360")
tk.Label(win,text="👤 User Profile",font=("Segoe UI",22,"bold")).pack(pady=20)
name=tk.StringVar(value=self.username)
tk.Label(win,text="Display name").pack(anchor="w",padx=30)
tk.Entry(win,textvariable=name,font=("Segoe UI",12)).pack(fill="x",padx=30,pady=8)
def save():
self.username=name.get().strip() or "User"; self.save_settings(); self.notify("Account","Profile updated."); self.close_window(win)
tk.Button(win,text="Save profile",command=save,bg="#0878c9",fg="white",relief="flat",padx=20,pady=8).pack(pady=15)
def keyboard_shortcuts(self):
win=self.new_window("Keyboard Shortcuts","620x500")
tk.Label(win,text="⌨ Keyboard shortcuts",font=("Segoe UI",22,"bold")).pack(pady=18)
items=[("Ctrl+Alt+D","Show desktop"),("Ctrl+Alt+R","Run"),("Ctrl+Alt+T","Terminal"),("Ctrl+Alt+L","Lock"),("Ctrl+Alt+S","Power menu"),("Ctrl+Alt+V","Virtual desktops"),("Ctrl+Alt+P","Paint"),("Ctrl+Alt+C","Calendar"),("Alt+Tab","Cycle windows"),("Ctrl+W","Close"),("Ctrl+M","Minimize"),("Ctrl+Shift+M","Maximize/restore"),("Alt+← / →","Snap left/right"),("Alt+↑ / ↓","Maximize/restore")]
for k,d in items: tk.Label(win,text=f"{k:<22} {d}",font=("Consolas",11),anchor="w").pack(fill="x",padx=35,pady=3)
def advanced_settings(self):
win=self.new_window("System Settings","720x560")
nb=ttk.Notebook(win); nb.pack(fill="both",expand=True,padx=10,pady=10)
p1=tk.Frame(nb); p2=tk.Frame(nb); p3=tk.Frame(nb); nb.add(p1,text="Account"); nb.add(p2,text="System"); nb.add(p3,text="Shortcuts")
tk.Label(p1,text="👤 Account",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p1,text="Edit user profile",command=self.user_profile).pack(anchor="w",padx=25,pady=6)
tk.Label(p1,text=f"Current user: {self.username}",fg="#666").pack(anchor="w",padx=25,pady=6)
tk.Label(p2,text="⚙ System",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p2,text="System Monitor",command=self.system_monitor).pack(anchor="w",padx=25,pady=5); tk.Button(p2,text="Virtual Desktops",command=self.virtual_desktops).pack(anchor="w",padx=25,pady=5)
tk.Label(p3,text="⌨ Shortcuts",font=("Segoe UI",20,"bold")).pack(anchor="w",padx=25,pady=20); tk.Button(p3,text="View all shortcuts",command=self.keyboard_shortcuts).pack(anchor="w",padx=25,pady=5)
# ---------- PythonOS 12 Pro Max ----------
def action_center(self):
win=self.new_window("Action Center","430x620")
win.configure(bg="#f4f4f4")
tk.Label(win,text="⚡ Action Center",font=("Segoe UI",20,"bold"),bg="#f4f4f4").pack(anchor="w",padx=20,pady=16)
q=tk.Frame(win,bg="#f4f4f4"); q.pack(fill="x",padx=15)
controls=[("📶 Wi-Fi",lambda:self.notify("Wi-Fi","PythonOS network control")),("🔵 Bluetooth",lambda:self.notify("Bluetooth","Bluetooth control")),("✈ Airplane mode",lambda:self.notify("Airplane mode","Toggled")),("🌙 Night light",lambda:self.notify("Night light","Toggled")),("🔊 Volume",self.quick_controls),("☀ Brightness",self.quick_controls)]
for text,cmd in controls:
tk.Button(q,text=text,command=cmd,width=17,height=2,relief="flat",bg="white").pack(side="left",padx=4,pady=4)
tk.Label(win,text="Notifications",font=("Segoe UI",14,"bold"),bg="#f4f4f4").pack(anchor="w",padx=20,pady=(18,8))
box=tk.Listbox(win,bd=0,bg="white",font=("Segoe UI",10)); box.pack(fill="both",expand=True,padx=20,pady=(0,15))
for n in self.notifications[-20:]: box.insert("end", f"{n[0]} — {n[1]}")
tk.Button(win,text="Clear all",command=lambda:(self.notifications.clear(),box.delete(0,"end")),relief="flat").pack(pady=(0,15))
def file_search_pro(self):
win=self.new_window("File Search Pro","760x520")
top=tk.Frame(win); top.pack(fill="x",padx=12,pady=12)
q=tk.StringVar(); ent=tk.Entry(top,textvariable=q,font=("Segoe UI",12)); ent.pack(side="left",fill="x",expand=True)
tree=ttk.Treeview(win,columns=("path","type","size"),show="headings")
for c,t,w in [("path","Path",480),("type","Type",100),("size","Size",100)]: tree.heading(c,text=t); tree.column(c,width=w)
tree.pack(fill="both",expand=True,padx=12,pady=(0,12))
roots=[os.path.expanduser("~"),os.path.join(os.path.expanduser("~"),"Desktop"),os.path.join(os.path.expanduser("~"),"Documents")]
def search_now():
tree.delete(*tree.get_children()); term=q.get().lower().strip()
if not term:return
count=0
for base in roots:
if not os.path.isdir(base): continue
for root,dirs,files in os.walk(base):
dirs[:]=[d for d in dirs if d not in {"AppData",".git","__pycache__"}]
for fn in files:
if term in fn.lower():
path=os.path.join(root,fn)
try: sz=os.path.getsize(path)
except: sz=0
tree.insert("","end",values=(path,os.path.splitext(fn)[1] or "File",f"{sz:,} B")); count+=1
if count>=200:return
tk.Button(top,text="Search",command=search_now,bg="#0078d7",fg="white",relief="flat",padx=18).pack(side="left",padx=8)
ent.bind("<Return>",lambda e:search_now()); ent.focus_set()
def clipboard_manager(self):
win=self.new_window("Clipboard Manager","520x430")
tk.Label(win,text="📋 Clipboard history",font=("Segoe UI",20,"bold")).pack(pady=15)
lb=tk.Listbox(win,font=("Segoe UI",10)); lb.pack(fill="both",expand=True,padx=20,pady=10)
try:
text=self.root.clipboard_get()
if text and (not self.clipboard_history or self.clipboard_history[-1]!=text): self.clipboard_history.append(text[:500])
except: pass
for x in reversed(self.clipboard_history[-30:]): lb.insert("end",x.replace("\n"," ")[:100])
def copy_back(e=None):
if lb.curselection():
text=list(reversed(self.clipboard_history[-30:]))[lb.curselection()[0]]
self.root.clipboard_clear(); self.root.clipboard_append(text)
lb.bind("<Double-Button-1>",copy_back)
tk.Button(win,text="Copy selected",command=copy_back,relief="flat").pack(pady=10)
def game_mode_toggle(self):
self.game_mode=not self.game_mode
state="ON" if self.game_mode else "OFF"
self.notify("Game Mode",f"Game Mode is {state}")
return self.game_mode
def recent_files_app(self):
win=self.new_window("Recent Files","650x430")
tk.Label(win,text="🕘 Recent files",font=("Segoe UI",20,"bold")).pack(pady=15)
lb=tk.Listbox(win,font=("Segoe UI",10)); lb.pack(fill="both",expand=True,padx=20,pady=10)
for p in reversed(self.recent_files[-50:]): lb.insert("end",p)
def themes(self):
win=self.new_window("Themes","600x430")
tk.Label(win,text="🎨 Themes",font=("Segoe UI",22,"bold")).pack(pady=18)
var=tk.StringVar(value=self.theme)
for name in ["Light","Dark","Blue"]:
tk.Radiobutton(win,text=name,variable=var,value=name,command=lambda:self.apply_theme(var.get())).pack(anchor="w",padx=50,pady=8)
tk.Button(win,text="Save theme",command=lambda:(self.apply_theme(var.get()),self.save_settings()),bg="#0078d7",fg="white",relief="flat",padx=20,pady=8).pack(pady=20)
def apply_theme(self,name):
self.theme=name
colors={"Light":"#f3f3f3","Dark":"#202020","Blue":"#0078d7"}
self.wallpaper=colors.get(name,"#0078d7"); self.save_settings()
self.notify("Personalization",f"Theme changed to {name}. Restart desktop to refresh all surfaces.")
def startup_apps(self):
win=self.new_window("Startup Apps","650x430")
tk.Label(win,text="🚀 Startup Apps",font=("Segoe UI",21,"bold")).pack(pady=15)
for n in ["PythonOS Shell","Notification Center","Clipboard Manager","System Monitor"]:
row=tk.Frame(win); row.pack(fill="x",padx=25,pady=5); tk.Label(row,text=n,font=("Segoe UI",11)).pack(side="left"); tk.Checkbutton(row,text="Enabled",onvalue=1,offvalue=0).pack(side="right")
def file_properties(self,path):
if not path:return
try:
st=os.stat(path); msg=f"Name: {os.path.basename(path)}\nType: {os.path.splitext(path)[1] or 'File'}\nSize: {st.st_size:,} bytes\nModified: {datetime.datetime.fromtimestamp(st.st_mtime)}\nPath: {path}"
messagebox.showinfo("Properties",msg,parent=self.root)
except Exception as e: messagebox.showerror("Properties",str(e),parent=self.root)
if __name__=="__main__":
root=tk.Tk()
PythonOS(root)
root.mainloop()
else :
print ("THE NUMBER IS NOT VALID ! Plese Open agen flie")
To embed this project on your website, copy the following code and paste it into your website's HTML: