1. Problem raising
When we use tkinter in python for programming, we often need a function that we can drag the interface at will and place it anywhere instead of just dragging the title bar, which makes our program more convenient and silky.
2. Problem analysis
If we want to implement this method, we can define functions or make a decorator. At that time, it is equivalent to adding a new function to our program, and this logic will be better understood.
3. Solve the problem
1. Directly use the function method
This method is the most primitive. We can directly add it to a program written in a function. By defining two functions, including on_drag_start and on_drag_motion, we can achieve the position movement of the interface by obtaining the new position of the mouse.
import tkinter as tk def on_drag_start(event): global x_start, y_start x_start = event.x_root y_start = event.y_root def on_drag_motion(event): global x_start, y_start delta_x = event.x_root - x_start delta_y = event.y_root - y_start x_new = root.winfo_x() + delta_x y_new = root.winfo_y() + delta_y (f"+{x_new}+{y_new}") x_start = event.x_root y_start = event.y_root root = () ("400x300") # Only bind event handlers to the background of the root window('<Button-1>', on_drag_start) ('<B1-Motion>', on_drag_motion) # Add a sample controlbutton = (root, text="Button") (pady=20) label = (root, text="Mobile Window") (pady=20) ()
2. Implement through a decorator
Although the function method can be implemented, we can put these two functions in the decorator and use the @ function name when calling. In the following code, we define a draggable_window decorator that can be used to add new functions to functions. We have added @draggable_window in front of create_window(), so that we can add new features to the new window.
import tkinter as tk def draggable_window(func): def wrapper(*args, **kwargs): root = func(*args, **kwargs) def on_drag_start(event): root.x_start = event.x_root root.y_start = event.y_root def on_drag_motion(event): delta_x = event.x_root - root.x_start delta_y = event.y_root - root.y_start x_new = root.winfo_x() + delta_x y_new = root.winfo_y() + delta_y (f"+{x_new}+{y_new}") root.x_start = event.x_root root.y_start = event.y_root ('<Button-1>', on_drag_start) ('<B1-Motion>', on_drag_motion) return root return wrapper @draggable_window def create_window(): root = () ("400x300") # Add control button = (root, text="Button") (pady=20) label = (root, text="Mobile Window") (pady=20) return root # Start the windowroot = create_window() ()
The DraggableWindow class encapsulates window creation, dragging functionality and control addition.
The on_drag_start and on_drag_motion methods handle the starting point of the drag and the drag process respectively.
The add_widgets method is used to add buttons and labels to the window.
The run method starts mainloop() to display the window.
3. Write the decorator into a class to decorate another program and add new functions
We can also define the decorator and put it in one class and directly modify the other class. The code is as follows, pay attention to the location of the decorator. This writing method is clear and organized. If you don’t want to use this drag function, just delete the decorator class directly.
import tkinter as tk # Decorators that define drag functiondef draggable(func): def wrapper(self, *args, **kwargs): func(self, *args, **kwargs) def on_drag_start(event): self.x_start = event.x_root self.y_start = event.y_root def on_drag_motion(event): delta_x = event.x_root - self.x_start delta_y = event.y_root - self.y_start x_new = .winfo_x() + delta_x y_new = .winfo_y() + delta_y (f"+{x_new}+{y_new}") self.x_start = event.x_root self.y_start = event.y_root # Bind drag event to window ('<Button-1>', on_drag_start) ('<B1-Motion>', on_drag_motion) return wrapper class DraggableWindow: @draggable def __init__(self): = () ("400x300") # Add control self.add_widgets() def add_widgets(self): button = (, text="Button") (pady=20) label = (, text="Mobile Window") (pady=20) def run(self): () # Start the windowapp = DraggableWindow() ()
In the above code, the draggable decorator is applied to the class's __init__ method, so that when the class is instantiated, the window will automatically bind the drag event.
The decorator is internally bound and dragged.
After encapsulation in this way, the logic of the drag function is encapsulated in the decorator, and the code of the class remains clear and concise.
3. After-study summary
1. In the future, in programming, commonly used functions may seem to be packaged into a decorator or a module that can be called, so as to separate the main program from some functional components, making it more convenient to modify and debug the program.
2. In today's learning, from the implementation of single function to the implementation of simple decorators and class decorators, the complexity has been further improved, and the logic of the application has become clearer.
3. Learning Python is a process of deepening understanding. If concepts like decorators are difficult to understand simply from a text, they can be placed in small projects and gradually digested to enhance understanding.
This is the article about how to implement the free drag of the graphical interface written in Python. For more related content related to free drag of the Python graphical interface, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!