└── main.py /main.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from ctypes import windll 3 | 4 | #this code works fine on windows 10, i didn't try it in any other OS, if you use window 8, 7, ... 5 | #or you use a distro of linux, you can try it anyway 6 | #this code works fine as a exe made in pyinstaller 7 | 8 | tk_title = "tk" # Put here your window title 9 | 10 | root=Tk() # root (your app doesn't go in root, it goes in window) 11 | root.title(tk_title) 12 | root.overrideredirect(True) # turns off title bar, geometry 13 | root.geometry('200x200+75+75') # set new geometry the + 75 + 75 is where it starts on the screen 14 | #root.iconbitmap("your_icon.ico") # to show your own icon 15 | root.minimized = False # only to know if root is minimized 16 | root.maximized = False # only to know if root is maximized 17 | 18 | LGRAY = '#3e4042' # button color effects in the title bar (Hex color) 19 | DGRAY = '#25292e' # window background color (Hex color) 20 | RGRAY = '#10121f' # title bar color (Hex color) 21 | 22 | root.config(bg="#25292e") 23 | title_bar = Frame(root, bg=RGRAY, relief='raised', bd=0,highlightthickness=0) 24 | 25 | 26 | def set_appwindow(mainWindow): # to display the window icon on the taskbar, 27 | # even when using root.overrideredirect(True 28 | # Some WindowsOS styles, required for task bar integration 29 | GWL_EXSTYLE = -20 30 | WS_EX_APPWINDOW = 0x00040000 31 | WS_EX_TOOLWINDOW = 0x00000080 32 | # Magic 33 | hwnd = windll.user32.GetParent(mainWindow.winfo_id()) 34 | stylew = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE) 35 | stylew = stylew & ~WS_EX_TOOLWINDOW 36 | stylew = stylew | WS_EX_APPWINDOW 37 | res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, stylew) 38 | 39 | mainWindow.wm_withdraw() 40 | mainWindow.after(10, lambda: mainWindow.wm_deiconify()) 41 | 42 | 43 | def minimize_me(): 44 | root.attributes("-alpha",0) # so you can't see the window when is minimized 45 | root.minimized = True 46 | 47 | 48 | def deminimize(event): 49 | 50 | root.focus() 51 | root.attributes("-alpha",1) # so you can see the window when is not minimized 52 | if root.minimized == True: 53 | root.minimized = False 54 | 55 | 56 | def maximize_me(): 57 | 58 | if root.maximized == False: # if the window was not maximized 59 | root.normal_size = root.geometry() 60 | expand_button.config(text=" 🗗 ") 61 | root.geometry(f"{root.winfo_screenwidth()}x{root.winfo_screenheight()}+0+0") 62 | root.maximized = not root.maximized 63 | # now it's maximized 64 | 65 | else: # if the window was maximized 66 | expand_button.config(text=" 🗖 ") 67 | root.geometry(root.normal_size) 68 | root.maximized = not root.maximized 69 | # now it is not maximized 70 | 71 | # put a close button on the title bar 72 | close_button = Button(title_bar, text=' × ', command=root.destroy,bg=RGRAY,padx=2,pady=2,font=("calibri", 13),bd=0,fg='white',highlightthickness=0) 73 | expand_button = Button(title_bar, text=' 🗖 ', command=maximize_me,bg=RGRAY,padx=2,pady=2,bd=0,fg='white',font=("calibri", 13),highlightthickness=0) 74 | minimize_button = Button(title_bar, text=' 🗕 ',command=minimize_me,bg=RGRAY,padx=2,pady=2,bd=0,fg='white',font=("calibri", 13),highlightthickness=0) 75 | title_bar_title = Label(title_bar, text=tk_title, bg=RGRAY,bd=0,fg='white',font=("helvetica", 10),highlightthickness=0) 76 | 77 | # a frame for the main area of the window, this is where the actual app will go 78 | window = Frame(root, bg=DGRAY,highlightthickness=0) 79 | 80 | # pack the widgets 81 | title_bar.pack(fill=X) 82 | close_button.pack(side=RIGHT,ipadx=7,ipady=1) 83 | expand_button.pack(side=RIGHT,ipadx=7,ipady=1) 84 | minimize_button.pack(side=RIGHT,ipadx=7,ipady=1) 85 | title_bar_title.pack(side=LEFT, padx=10) 86 | window.pack(expand=1, fill=BOTH) # replace this with your main Canvas/Frame/etc. 87 | #xwin=None 88 | #ywin=None 89 | # bind title bar motion to the move window function 90 | 91 | def changex_on_hovering(event): 92 | global close_button 93 | close_button['bg']='red' 94 | 95 | 96 | def returnx_to_normalstate(event): 97 | global close_button 98 | close_button['bg']=RGRAY 99 | 100 | 101 | def change_size_on_hovering(event): 102 | global expand_button 103 | expand_button['bg']=LGRAY 104 | 105 | 106 | def return_size_on_hovering(event): 107 | global expand_button 108 | expand_button['bg']=RGRAY 109 | 110 | 111 | def changem_size_on_hovering(event): 112 | global minimize_button 113 | minimize_button['bg']=LGRAY 114 | 115 | 116 | def returnm_size_on_hovering(event): 117 | global minimize_button 118 | minimize_button['bg']=RGRAY 119 | 120 | 121 | def get_pos(event): # this is executed when the title bar is clicked to move the window 122 | if root.maximized == False: 123 | 124 | xwin = root.winfo_x() 125 | ywin = root.winfo_y() 126 | startx = event.x_root 127 | starty = event.y_root 128 | 129 | ywin = ywin - starty 130 | xwin = xwin - startx 131 | 132 | 133 | def move_window(event): # runs when window is dragged 134 | root.config(cursor="fleur") 135 | root.geometry(f'+{event.x_root + xwin}+{event.y_root + ywin}') 136 | 137 | 138 | def release_window(event): # runs when window is released 139 | root.config(cursor="arrow") 140 | 141 | 142 | title_bar.bind('', move_window) 143 | title_bar.bind('', release_window) 144 | title_bar_title.bind('', move_window) 145 | title_bar_title.bind('', release_window) 146 | else: 147 | expand_button.config(text=" 🗖 ") 148 | root.maximized = not root.maximized 149 | 150 | title_bar.bind('', get_pos) # so you can drag the window from the title bar 151 | title_bar_title.bind('', get_pos) # so you can drag the window from the title 152 | 153 | # button effects in the title bar when hovering over buttons 154 | close_button.bind('',changex_on_hovering) 155 | close_button.bind('',returnx_to_normalstate) 156 | expand_button.bind('', change_size_on_hovering) 157 | expand_button.bind('', return_size_on_hovering) 158 | minimize_button.bind('', changem_size_on_hovering) 159 | minimize_button.bind('', returnm_size_on_hovering) 160 | 161 | # resize the window width 162 | resizex_widget = Frame(window,bg=DGRAY,cursor='sb_h_double_arrow') 163 | resizex_widget.pack(side=RIGHT,ipadx=2,fill=Y) 164 | 165 | 166 | def resizex(event): 167 | xwin = root.winfo_x() 168 | difference = (event.x_root - xwin) - root.winfo_width() 169 | 170 | if root.winfo_width() > 150 : # 150 is the minimum width for the window 171 | try: 172 | root.geometry(f"{ root.winfo_width() + difference }x{ root.winfo_height() }") 173 | except: 174 | pass 175 | else: 176 | if difference > 0: # so the window can't be too small (150x150) 177 | try: 178 | root.geometry(f"{ root.winfo_width() + difference }x{ root.winfo_height() }") 179 | except: 180 | pass 181 | 182 | resizex_widget.config(bg=DGRAY) 183 | 184 | resizex_widget.bind("",resizex) 185 | 186 | # resize the window height 187 | resizey_widget = Frame(window,bg=DGRAY,cursor='sb_v_double_arrow') 188 | resizey_widget.pack(side=BOTTOM,ipadx=2,fill=X) 189 | 190 | def resizey(event): 191 | ywin = root.winfo_y() 192 | difference = (event.y_root - ywin) - root.winfo_height() 193 | 194 | if root.winfo_height() > 150: # 150 is the minimum height for the window 195 | try: 196 | root.geometry(f"{ root.winfo_width() }x{ root.winfo_height() + difference}") 197 | except: 198 | pass 199 | else: 200 | if difference > 0: # so the window can't be too small (150x150) 201 | try: 202 | root.geometry(f"{ root.winfo_width() }x{ root.winfo_height() + difference}") 203 | except: 204 | pass 205 | 206 | resizex_widget.config(bg=DGRAY) 207 | 208 | resizey_widget.bind("",resizey) 209 | 210 | # some settings 211 | root.bind("",deminimize) # to view the window by clicking on the window icon on the taskbar 212 | root.after(10, lambda: set_appwindow(root)) # to see the icon on the task bar 213 | 214 | 215 | #YOUR CODE GOES between the lines :) 216 | # =================================================================================================== 217 | 218 | 219 | 220 | 221 | 222 | # Uncomment below to see example of packing a label 223 | #Label(window,text="Hello :D",bg=DGRAY,fg="#fff").pack(expand=1) # example 224 | 225 | 226 | 227 | 228 | 229 | # =================================================================================================== 230 | 231 | root.mainloop() 232 | --------------------------------------------------------------------------------