This issue would happen on Windows. Your code works fine on Linux.(I've tested it)
A possible reason is here:
What is happening here (simplyfied a lot) is that as soon as Windows detects a button-down event on the non-client area it stops sending update messages, gets a snapshot of the window and gets ready to start drawing all those nice effects for window-moving, -resizing, etc. The window then stays frozen until the corresponding mouse-up ends the impasse.
This post also mentioned another solution: use thread.
Due to tkinter is single-threaded and those features are packaged, it seems using thread doesn't work in tkinter.
The cause is how operate system handle those "holding down" events on the title bar.
An easy solution is just hiding your title bar, and custom these buttons by yourself.(Avoid OS handling those events.) Like:
from tkinter import Tk, Toplevel, Scale
import tkinter as tk
class CustomToplevel(Toplevel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__offset_x = 100
self.__offset_y = 100
self.window_width = 100
self.window_height = 100
self.overrideredirect(True)
self.title_bar_frame = tk.Frame(self, bg="grey")
self.title_bar_frame.pack(fill="x")
self.title_bar_frame.bind('<Button-1>', self.__click)
self.title_bar_frame.bind('<B1-Motion>',self.__drag)
self.close_button = tk.Button(self.title_bar_frame, text="X", bg="red", font=("", 15),
command=self.destroy)
self.close_button.pack(side="right", fill="y")
self.geometry(f"{self.window_width}x{self.window_height}+{self.winfo_pointerx() - self.__offset_x}+{self.winfo_pointery() - self.__offset_y}")
def __click(self, event):
self.__offset_x = event.x
self.__offset_y = event.y
def __drag(self, event):
self.geometry(f"{self.window_width}x{self.window_height}+{self.winfo_pointerx() - self.__offset_x}+{self.winfo_pointery() - self.__offset_y}")
root = Tk()
slider = Scale(root, orient='horizontal')
slider.pack()
num = 0
def main():
global num
slider.set(num)
num += 1
slider.after(500, main)
def toplevel():
win = CustomToplevel()
root.bind('<space>', lambda x: [main(), toplevel()])
root.mainloop()
Binding some events or using some nice color makes your UI prettier.