Table of contents
2 Implement the drag and drop function
3 Multithreading and asynchronous programming
4 Adding animations and transitions
5 Multi-interface and multi-threading example
Column Guide
Column subscription address: https://blog.csdn.net/qq_35831906/category_12375510.html
1. Advanced GUI functions
1 Customize themes and styles
Custom themes and styles can make your GUI application look great. ttkthemes
You can use libraries to apply different themes and styles when using Tkinter .
pip install ttkthemes
Next, try the following sample code to apply different themes and styles:
import tkinter as tk
from tkinter import ttk
from ttkthemes import ThemedStyle
def change_theme():
selected_theme = theme_var.get()
style.set_theme(selected_theme)
root = tk.Tk()
root.title("Custom Theme Example")
style = ThemedStyle(root)
# 创建一个下拉框,用于选择主题
theme_var = tk.StringVar()
theme_var.set(style.theme_use()) # 默认选中当前主题
theme_dropdown = ttk.Combobox(root, textvariable=theme_var, values=style.theme_names())
theme_dropdown.pack()
# 创建一个按钮,用于应用选定的主题
apply_button = ttk.Button(root, text="Apply Theme", command=change_theme)
apply_button.pack()
label = ttk.Label(root, text="Custom Theme Example")
label.pack(padx=20, pady=20)
root.mainloop()
The output effect is as follows:
In this example, we create a dropdown box that allows the user to select a different theme. When the user selects a theme and clicks the "Apply Theme" button, the application will apply the corresponding styles according to the selected theme.
If you still can't see the different theme effects after running this example, please make sure that your operating system and Python environment both support the "ttkthemes" library correctly. Sometimes certain themes may not work properly in certain environments. In this case, you can try running the sample in a different environment to see if the different themes are displayed correctly.
2 Implement the drag and drop function
Drag and drop functionality allows users to drag a control from one location to another. Here is an example of drag and drop using Tkinter:
import tkinter as tk
def on_drag_start(event):
event.widget.start_x = event.x
event.widget.start_y = event.y
def on_drag_motion(event):
delta_x = event.x - event.widget.start_x
delta_y = event.y - event.widget.start_y
event.widget.place(x=event.widget.winfo_x() + delta_x, y=event.widget.winfo_y() + delta_y)
event.widget.start_x = event.x
event.widget.start_y = event.y
root = tk.Tk()
label = tk.Label(root, text="Drag me!")
label.place(x=50, y=50)
label.bind("<Button-1>", on_drag_start)
label.bind("<B1-Motion>", on_drag_motion)
root.mainloop()
The output is as follows:
3 Multithreading and asynchronous programming
In GUI programming, multithreading and asynchronous programming are crucial to ensure responsive and smooth application interface. Use multithreading to handle time-consuming operations in the background, and asynchronous programming to avoid blocking the user interface in some cases. Let me explain these two concepts in detail and provide sample code for you.
Multithreading
threading
Multithreading can be achieved in Python applications using modules. This is useful for performing some time-consuming operations (such as network requests or calculations) in the background so as not to block the GUI interface.
The following is an example of using a threading
module, where a thread updates the label content on the GUI interface:
import tkinter as tk
import threading
import time
def update_label():
for i in range(100):
label.config(text=f"Count: {i}")
time.sleep(1)
root = tk.Tk()
label = tk.Label(root, text="Count: 0")
label.pack()
thread = threading.Thread(target=update_label)
thread.start()
root.mainloop()
The output is as follows:
In this example, we create a new thread to update the content of the label without blocking the GUI event loop in the main thread.
asynchronous programming
Using asyncio
modules enables asynchronous programming in Python applications, allowing for better handling of concurrent tasks. Asynchronous programming is suitable for situations where you need to wait for IO operations (such as network requests) to complete.
Here's a simple example of using a asyncio
module where a coroutine waits for a while and then updates a label on the GUI:
import tkinter as tk
import asyncio
async def update_label():
for i in range(10):
label.config(text=f"Count: {i}")
await asyncio.sleep(1)
root = tk.Tk()
label = tk.Label(root, text="Count: 0")
label.pack()
async def main():
await update_label()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
root.mainloop()
In this example, we use
asyncio
modules to create a coroutine, and then use an asynchronous event loop to run the coroutine.Note that GUI frameworks such as Tkinter may have some restrictions on multithreading and asynchronous programming. Make sure to follow the framework's relevant rules and best practices when doing multi-threaded or asynchronous programming to avoid potential problems.
Both multithreading and asynchronous programming are meant to ensure responsive and fluid GUI applications, allowing you to perform tasks in the background without blocking the UI.
2. Practical projects
1. To-do application
A simple to-do list app allows users to add, edit and delete tasks and display them on the interface. Here is a Tkinter based example:
import tkinter as tk
from tkinter import messagebox
def add_task():
task = entry.get()
if task:
tasks_listbox.insert(tk.END, task)
entry.delete(0, tk.END)
else:
messagebox.showwarning("Warning", "Please enter a task.")
def delete_task():
selected_task = tasks_listbox.curselection()
if selected_task:
tasks_listbox.delete(selected_task)
root = tk.Tk()
root.title("To-Do List")
entry = tk.Entry(root)
entry.pack()
add_button = tk.Button(root, text="Add Task", command=add_task)
add_button.pack()
delete_button = tk.Button(root, text="Delete Task", command=delete_task)
delete_button.pack()
tasks_listbox = tk.Listbox(root)
tasks_listbox.pack()
root.mainloop()
output:
2. Image Viewer
A simple image viewer allows users to open and view image files. Here is a Tkinter based example:
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
def open_image():
file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.png *.jpg *.jpeg")])
if file_path:
image = Image.open(file_path)
photo = ImageTk.PhotoImage(image)
label.config(image=photo)
label.photo = photo
root = tk.Tk()
root.title("Image Viewer")
open_button = tk.Button(root, text="Open Image", command=open_image)
open_button.pack()
label = tk.Label(root)
label.pack()
root.mainloop()
3. Text editor
A basic text editor allows users to open, edit and save text files. Here is a Tkinter based example:
import tkinter as tk
from tkinter import filedialog
def open_file():
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
if file_path:
with open(file_path, "r") as file:
text.delete("1.0", tk.END)
text.insert(tk.END, file.read())
def save_file():
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
if file_path:
with open(file_path, "w") as file:
file.write(text.get("1.0", tk.END))
root = tk.Tk()
root.title("Text Editor")
open_button = tk.Button(root, text="Open File", command=open_file)
open_button.pack()
save_button = tk.Button(root, text="Save File", command=save_file)
save_button.pack()
text = tk.Text(root)
text.pack()
root.mainloop()
4 Adding animations and transitions
Adding animations and transition effects in GUI applications can enhance the user experience and make the application more attractive. The following is an example showing how to create a simple GUI application in Tkinter and add animations and transitions.
import tkinter as tk
import time
class AnimatedApp:
def __init__(self, root):
self.root = root
self.root.title("Animated GUI App")
self.label = tk.Label(root, text="Welcome!", font=("Helvetica", 24))
self.label.pack(pady=50)
self.button = tk.Button(root, text="Animate", command=self.animate)
self.button.pack()
def animate(self):
initial_x = self.label.winfo_x()
target_x = 300 # Target x-coordinate for animation
while initial_x < target_x:
initial_x += 5 # Increment x-coordinate
self.label.place(x=initial_x, y=100)
self.root.update() # Update GUI to reflect changes
time.sleep(0.05) # Add a short delay for animation effect
self.label.config(text="Animation Complete!")
root = tk.Tk()
app = AnimatedApp(root)
root.mainloop()
5 Multi-interface and multi-threading example
Handling the combined situation of multiple windows and multiple threads requires careful handling to ensure UI responsiveness and thread safety. The following is an example that demonstrates how to create a multi-window application in Tkinter and use multiple threads to perform time-consuming operations.
import tkinter as tk
import threading
import time
class MainWindow:
def __init__(self, root):
self.root = root
self.root.title("Multi-Window App")
self.root.configure(bg="lightblue") # Set background color
self.open_button = tk.Button(root, text="Open New Window", command=self.open_new_window)
self.open_button.pack()
def open_new_window(self):
new_window = tk.Toplevel(self.root)
child_window = ChildWindow(new_window)
class ChildWindow:
def __init__(self, root):
self.root = root
self.root.title("Child Window")
self.root.configure(bg="lightgreen") # Set background color
# Calculate child window position within main window
main_x = self.root.master.winfo_rootx()
main_y = self.root.master.winfo_rooty()
main_width = self.root.master.winfo_width()
main_height = self.root.master.winfo_height()
window_width = 300
window_height = 200
x_position = main_x + (main_width - window_width) // 2
y_position = main_y + (main_height - window_height) // 2
# Ensure the child window is within the main window boundaries
if x_position < main_x:
x_position = main_x
if y_position < main_y:
y_position = main_y
self.root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
self.label = tk.Label(root, text="Child Window", font=("Helvetica", 16), bg="lightgreen", fg="black") # Set foreground color
self.label.pack(pady=20)
self.start_button = tk.Button(root, text="Start Task", command=self.start_task, bg="lightblue") # Set button color
self.start_button.pack()
def start_task(self):
thread = threading.Thread(target=self.long_running_task)
thread.start()
def long_running_task(self):
self.start_button.config(state=tk.DISABLED) # Disable the button during task
for i in range(10):
print(f"Task running: {i}")
time.sleep(1)
self.start_button.config(state=tk.NORMAL) # Enable the button after task
root = tk.Tk()
app = MainWindow(root)
root.geometry("400x300") # Set initial main window size
root.mainloop()
In this example, we create a main window and a child window. Clicking the "Open New Window" button will open a new sub-window. There is a "Start Task" button in the sub-window. Clicking it will start a multi-threaded task (simulating time-consuming operations), and disable the button while the task is in progress. The task Re-enable the button when done.
Pay attention to the following points:
- Use
Toplevel
to create child windows.- Use
threading
modules to implement multithreading. The task here is just a simple example of waiting, in reality it can be any time-consuming operation.- Since
tkinter
it is not thread-safe, make sure to manipulate GUI elements in the main thread, using threads to perform time-consuming tasks.To avoid problems such as thread conflicts and interface freezes, it is necessary to carefully manage the life cycle, state, and interaction with the GUI of threads.