【100天精通python】Day36:GUI界面编程_Tkinter高级功能操作和示例

news2025/1/18 20:25:33

目录

 专栏导读 

一、GUI 高级功能

1 自定义主题和样式

2 实现拖放功能

 3 多线程和异步编程

二、实战项目

1. 待办事项应用

2. 图像查看器

3. 文本编辑器

4 添加动画和过渡效果

 5 多界面和多线程示例  


 专栏导读 

专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12375510.html


一、GUI 高级功能

1 自定义主题和样式

        自定义主题和样式可以让你的GUI应用程序在外观方面更加出色。在使用Tkinter时,你可以使用ttkthemes库来应用不同的主题和样式。

pip install ttkthemes

接下来,尝试以下示例代码,以便应用不同的主题和样式: 

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()

输出效果如下: 

        在这个示例中,我们创建了一个下拉框,允许用户选择不同的主题。当用户选择主题并点击"Apply Theme"按钮时,应用程序将根据选择的主题来应用相应的样式。

        如果在运行此示例后仍然无法看到不同的主题效果,请确保你的操作系统和Python环境都能够正确地支持"ttkthemes"库。有时候在某些环境中,特定的主题可能无法正常工作。在这种情况下,你可以尝试在其他环境中运行示例,以查看是否能够正确显示不同的主题。

2 实现拖放功能

        拖放功能允许用户将一个控件从一个位置拖到另一个位置。以下是一个使用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()

输出如下: 

 3 多线程和异步编程

         在GUI编程中,多线程和异步编程是为了确保应用界面的响应性和流畅性而至关重要的。使用多线程可以在后台处理耗时操作,而异步编程则可以在某些情况下避免阻塞用户界面。让我为你详细解释这两个概念,并提供示例代码。

多线程

        使用threading模块可以在Python应用程序中实现多线程。这对于在后台执行一些耗时的操作(例如网络请求或计算)非常有用,以免阻塞GUI界面。

以下是一个使用threading模块的示例,其中一个线程会更新GUI界面上的标签内容:

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()

 输出如下:

         在这个示例中,我们创建了一个新的线程来更新标签的内容,而不会阻塞主线程中的GUI事件循环。

 异步编程

        使用asyncio模块可以在Python应用程序中实现异步编程,从而更好地处理并发任务。异步编程适用于需要等待IO操作(如网络请求)完成的情况。

        以下是一个使用asyncio模块的简单示例,其中一个协程会等待一段时间,然后更新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()

        在这个示例中,我们使用了asyncio模块来创建一个协程,然后使用异步事件循环来运行协程。

        请注意,GUI框架(如Tkinter)可能对多线程和异步编程有一些限制。确保在进行多线程或异步编程时,遵循框架的相关规则和最佳实践,以避免潜在的问题。

        多线程和异步编程都是为了确保GUI应用的响应性和流畅性,允许你在后台执行任务而不阻塞用户界面。

二、实战项目

1. 待办事项应用

一个简单的待办事项应用可以让用户添加、编辑和删除任务,并将它们显示在界面上。以下是一个基于Tkinter的示例:

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()

 输出:

2. 图像查看器

一个简单的图像查看器可以让用户打开并查看图片文件。以下是一个基于Tkinter的示例:

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. 文本编辑器

一个基本的文本编辑器可以让用户打开、编辑和保存文本文件。以下是一个基于Tkinter的示例:

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 添加动画和过渡效果

        在GUI应用中添加动画和过渡效果可以增强用户体验,使应用更具吸引力。以下是一个示例,演示如何在Tkinter中创建一个简单的GUI应用,并添加动画和过渡效果。

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 多界面和多线程示例  

        处理多窗口和多线程的综合情况需要小心处理,以确保界面响应性和线程安全。以下是一个示例,演示如何在Tkinter中创建一个多窗口应用,并使用多线程来执行耗时操作。

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()

        在这个示例中,我们创建了一个主窗口和一个子窗口。点击"Open New Window"按钮会打开一个新的子窗口,子窗口中有一个"Start Task"按钮,点击它会启动一个多线程任务(模拟耗时操作),并在任务进行时禁用按钮,任务完成后重新启用按钮。

要注意以下几点:

  • 使用Toplevel来创建子窗口。
  • 使用threading模块来实现多线程。这里的任务只是一个简单的等待示例,实际中可以是任何耗时操作。
  • 由于tkinter不是线程安全的,确保在主线程中操作GUI元素,使用线程来执行耗时任务。

要避免出现线程冲突和界面卡顿等问题,需要仔细管理线程的生命周期、状态以及与GUI之间的交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/896080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端-初始化Vue3+TypeScript

如果使用如下命令初始化项目&#xff0c;项目很干净&#xff0c;很适合了解项目的各个结构。 npm init vitelatest如果使用如下命令初始化项目&#xff0c;是可以选择你需要的组件 npm init vuelatest

Docker 容器数据卷

Docker挂载主机目录访问如果出现cannot open directory .: Permission denied 解决办法&#xff1a;在挂载目录后多加一个--privilegedtrue参数即可 如果是CentOS7安全模块会比之前系统版本加强&#xff0c;不安全的会先禁止&#xff0c;所以目录挂载的情况被默认为不安全的行…

你家的wifi安全么?

在移动互联网已经相当普及的今天&#xff0c;家用Wifi已经成为居家必备设备了&#xff0c;但你有没有考虑过这样一个问题&#xff0c;“我家的Wifi安全么&#xff0c;有没有可能被别人蹭网&#xff0c;或者被黑客登录进来&#xff0c;窃取数据&#xff1f;”下面就结合目前主流…

Bryntum Scheduler Pro 5.5.1 Crack

BRYNTUM 调度程序专业版,专业的日程安排小部件 Bryntum Scheduler Pro 5.5.1 一个专业有大脑的调度UI组件。Scheduler Pro 可帮助您安排任务&#xff0c;同时考虑资源和任务的可用性。 连接您的任务 让 Scheduler Pro 处理剩下的事情。它将根据您定义的链接安排您的任务并遵守任…

3D echarts在vue中的使用

注意&#xff1a;高度问题要如此设置即可解决 参考1 参考2

由于找不到d3dx9_43.dll无法继续执行代码怎么解决

我们在安装PS&#xff0c;吃鸡等软件跟游戏的时候&#xff0c;有可能安装完之后出现以下问题&#xff08;特别是win7或者win8系统&#xff09; 错误&#xff1a; 打开PS或者吃鸡等游戏的时候出现这个错误&#xff1a;无法启动此程序&#xff0c;因为计算机中丢失d3dx9_43.dll。…

如何让多线程步调一致?

前几天老板突然匆匆忙忙的过来说对账系统最近越来越慢了&#xff0c;能不能快速优化一下&#xff1f;我了解了对账系统的业务后&#xff0c;发现还是挺简单的&#xff0c;用户通过在线商城下单&#xff0c;会生成电子订单&#xff0c;保存在订单库。之后物流会生成派送单给用户…

免费写真软件让你畅享写真之旅

佳媛: 嗨&#xff0c;妙纯&#xff0c;听说你喜欢拍摄写真照&#xff0c;那你有什么简单的写真照制作方式推荐吗&#xff1f; 妙纯&#xff1a;当然&#xff0c;现在有很多古装写真软件&#xff0c;你可以利用这些软件来制作写真照片哦。 佳媛: 哦&#xff1f;那拍古装写真软…

Apache JMeter

下载 Apache JMeter 并安装 java链接 打开 apache-jmeter-5.4.1\bin 找到jmeter.bat 双击打开 或者 ApacheJMeter.jar 双击打开 设置中文 找到 options 》choose Language 》chinese 新建 计划 创建线程组 添加Http请求 配置元件添加请求头参数&#xff08;content-type&…

LVS - DR

LVS-DR 数据流向 客户端发送请求到 Director Server&#xff08;负载均衡器&#xff09;&#xff0c;请求的数据报文&#xff08;源 IP 是 CIP,目标 IP 是 VIP&#xff09;到达内核空间。Director Server 和 Real Server 在同一个网络中&#xff0c;数据通过二层数据链路层来传…

miniconda克隆arcpy

arcpy环境克隆 前言尝试思考到此结束 前言 最近遇到了一些问题&#xff0c;需要用到arcpy来处理一些东西&#xff0c;但众所周知&#xff0c;arcgis的arcpy是python 2.0的&#xff0c;我不是很喜欢&#xff1b;所以我安装了arcgis pro 2.8&#xff0c;我发现这也是个坑&#x…

Redis高可用:主从复制详解

目录 1.什么是主从复制&#xff1f; 2.优势 3.主从复制的原理 4.全量复制和增量复制 4.1 全量复制 4.2 增量复制 5.相关问题总结 5.1 当主服务器不进行持久化时复制的安全性 5.2 为什么主从全量复制使用RDB而不使用AOF&#xff1f; 5.3 为什么还有无磁盘复制模式&#xff…

【学习FreeRTOS】第10章——FreeRTOS时间片调度

1.时间片调度简介&#xff08;同第2章1.3&#xff09; 同等优先级任务轮流地享有相同的 CPU 时间(可设置)&#xff0c; 叫时间片&#xff0c;在FreeRTOS中&#xff0c;一个时间片就等于SysTick 中断周期 首先Task1运行完一个时间片后&#xff0c;切换至Task2运行Task2运行完…

从SaaS到RPA,没有真正“完美”的解决方案!

众所周知&#xff0c;SaaS行业越来越卷&#xff0c;利润也越来越“薄”&#xff0c;这是传统软件厂商的悲哀&#xff0c;也是未来数字化行业不得不面对的冷峻现状之一。 随着基于aPaaS、低代码的解决方案之流行&#xff0c;SaaS行业变得越来越没有技术门槛&#xff0c;IT人员的…

Vue3.X 创建简单项目

一、环境安装与检查 首先&#xff0c;我们要确保我们安装了构建vue框架的环境&#xff0c;不会安装的请自行百度&#xff0c;有很多安装教程。检查环境 node -v # 如果没有安装nodejs请安装&#xff0c;安装教程自行百度 vue -V# 没有安装&#xff0c;请执行npm install -g v…

数据挖掘 | 零代码采集房源数据,支持自动翻页、数据排重等

1 前言 城市规划、商业选址等应用场景中经常会对地区房价、地域价值进行数据分析&#xff0c;其中地区楼盘房价是分析数据中重要的信息参考点&#xff0c;一些互联网网站上汇聚了大量房源信息&#xff0c;通过收集此类数据&#xff0c;能够对地区房价的分析提供参考依据。 如何…

ld链接文件和startup文件分析和优化--基于RT1176

ld链接文件关系到程序的代码段数据段bss段及其用户自定义段的运行位置&#xff0c;ld文件中的各个段都会在main函数之前&#xff0c;从加载域拷贝到运行域中。本章将具体介绍如何修改ld和startup文件。 软件平台&#xff1a;VSCODEGCC工具链 硬件平台&#xff1a;rt1176开发板…

如何在HTML中使用React

突发奇想 查了查真的可以,官方文档: 在网站中添加 React – React 开始 引入js <!-- 开发环境使用 --><script src"https://unpkg.com/react18/umd/react.development.js"></script><script src"https://unpkg.com/react-dom18/umd/reac…

ROS局部路径规划器插件teb_local_planner流程梳理(下)

在我之前的文章《ROS导航包Navigation中的 Movebase节点路径规划相关流程梳理》中已经介绍过Move_base节点调用局部路径规划器插件的接口函数是computeVelocityCommands&#xff0c;本部分来&#xff0c;我们从这个函数入手梳理teb_local_planner功能包的工作流程。 ☆注&#…

进入银行科技部半年,已经丧失跳槽的能力了

大家好&#xff0c;我是锋哥!&#xff01; 学弟分享 我是一个杭州双非的本科生&#xff0c;2022届毕业之后进了某银行的科技部工作&#xff0c;年包 20w。 当时想着在银行也算是一份安稳的工作&#xff0c;因此选择了给钱最多的一个&#xff0c;想着自己走上了金融 科技的赛…