当前位置: 首页 > news >正文

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

 专栏导读 

专栏订阅地址: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 ThemedStyledef 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 tkdef on_drag_start(event):event.widget.start_x = event.xevent.widget.start_y = event.ydef on_drag_motion(event):delta_x = event.x - event.widget.start_xdelta_y = event.y - event.widget.start_yevent.widget.place(x=event.widget.winfo_x() + delta_x, y=event.widget.winfo_y() + delta_y)event.widget.start_x = event.xevent.widget.start_y = event.yroot = 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 timedef 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 asyncioasync 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 messageboxdef 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, ImageTkdef 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 = photoroot = 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 filedialogdef 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 timeclass AnimatedApp:def __init__(self, root):self.root = rootself.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 animationwhile initial_x < target_x:initial_x += 5  # Increment x-coordinateself.label.place(x=initial_x, y=100)self.root.update()  # Update GUI to reflect changestime.sleep(0.05)  # Add a short delay for animation effectself.label.config(text="Animation Complete!")root = tk.Tk()
app = AnimatedApp(root)
root.mainloop()

 5 多界面和多线程示例  

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

import tkinter as tk
import threading
import timeclass MainWindow:def __init__(self, root):self.root = rootself.root.title("Multi-Window App")self.root.configure(bg="lightblue")  # Set background colorself.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 = rootself.root.title("Child Window")self.root.configure(bg="lightgreen")  # Set background color# Calculate child window position within main windowmain_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 = 300window_height = 200x_position = main_x + (main_width - window_width) // 2y_position = main_y + (main_height - window_height) // 2# Ensure the child window is within the main window boundariesif x_position < main_x:x_position = main_xif y_position < main_y:y_position = main_yself.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 colorself.label.pack(pady=20)self.start_button = tk.Button(root, text="Start Task", command=self.start_task, bg="lightblue")  # Set button colorself.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 taskfor i in range(10):print(f"Task running: {i}")time.sleep(1)self.start_button.config(state=tk.NORMAL)  # Enable the button after taskroot = tk.Tk()
app = MainWindow(root)
root.geometry("400x300")  # Set initial main window sizeroot.mainloop()

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

要注意以下几点:

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

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

相关文章:

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

专栏导读 专栏订阅地址&#xff1a;https://blog.csdn.net/qq_35831906/category_12375510.html 一、GUI 高级功能 1 自定义主题和样式 自定义主题和样式可以让你的GUI应用程序在外观方面更加出色。在使用Tkinter时&#xff0c;你可以使用ttkthemes库来应用不同的主题和样式。…...

无涯教程-Perl - sub函数

描述 此函数定义一个新的子例程。上面显示的参数遵循以下规则- NAME是子例程的名称。可以在有或没有原型规范的情况下预先声明命名的子例程(没有关联的代码块)。 匿名子例程必须具有定义。 PROTO定义了函数的原型,调用该函数以验证提供的参数时将使用该原型。 ATTRS为解析…...

wpf控件上移下移,调整子集控件显示顺序

页面代码: <!-- 导出A2,自定义导出设置列,添加时间:2023-8-9 14:14:18,作者:whl; --><Window x:Class="WpfSnqkGasAnalysis.WindowGasExportA2"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http:/…...

cesium学习记录08-鼠标绘制多边形

上一篇学习了实体的一些基础知识&#xff0c;这一篇来学习鼠标绘制实体多边形的实现 一、方法一&#xff1a; 1&#xff0c;结果显示 贴地&#xff1a; 不贴地&#xff1a; 2&#xff0c;方法全部代码&#xff1a; 主方法&#xff1a; /*** 绘制多边形* param {Object} op…...

rocketMq启动broker报错找不到或无法加载主类 Files\Java\jdk1.8.0_171\lib\dt.jar;C:\Program]

假如弹出提示框提示‘错误: 找不到或无法加载主类 xxxxxx’。 1.打开runbroker.cmd 将"%CLASSPATH%"加上英文双引号&#xff0c;切勿别加中文双引号 2.打开runserver.cmd 同理 将"%CLASSPATH%"加上英文双引号&#xff0c;切勿别加中文双引号 3.正常执行即…...

Linux touch 命令指南大全

1. 概述 在本教程中,我们将学习touch命令。简而言之,这个命令允许我们更新文件或目录的最后修改时间和最后访问时间。 因此,我们将重点关注如何使用该命令及其各种选项。 请注意,我们使用 Bash 测试了此处显示的所有命令;但是,它们应该与任何兼容 POSIX 的 shell 一起使…...

华为网络篇 RIPv2的基础配置-25

难度 1复杂度1 目录 一、实验原理 1.1 RIP的版本 1.2 RIP的路由更新方式 1.3 RIP的计时器 1.4 RIP的防环机制 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;&am…...

fastadmin 下拉多级分类

要实现下图效果 一、先创建数据表 二、在目标的controll中引入use fast\Tree; public function _initialize() {parent::_initialize();$this->model new \app\admin\model\zxdc\Categorys;$tree Tree::instance();$tree->init(collection($this->model->order(…...

时序预测 | MATLAB实现基于CNN-LSTM卷积长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于CNN-LSTM卷积长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于CNN-LSTM卷积长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍 MATLAB实现基…...

RabbitMQ工作流程详解

1 生产者发送消息的流程 (1)生产者连接RabbitMQ&#xff0c;建立TCP连接(Connection)&#xff0c;开启信道(Channel) (2)生产者声明一个Exchange (交换器)&#xff0c;并设置相关属性&#xff0c;比如交换器类型、是否持久化等 (3)生产者声明一个队列井设置相关属性&#xf…...

LabVIEW使用图像处理进行交通控制性能分析

LabVIEW使用图像处理进行交通控制性能分析 采用普雷维特、拉普拉斯、索贝尔和任意的空间域方法对存储的图像进行边缘检测&#xff0c;并获取实时图像。然而&#xff0c;对四种不同空间域边缘检测方法的核的性能分析。 以前&#xff0c;空路图像存储在数据库中&#xff0c;道路…...

CentOS 7 下 Keepalived + Nginx 实现双机高可用

CentOS 7 下 Keepalived Nginx 实现双机高可用 文章目录 CentOS 7 下 Keepalived Nginx 实现双机高可用服务器准备服务信息服务架构 服务安装nginxKeepalived 服务配置nginxKeepalived 启动服务nginxkeepalived 服务验证查看 VIP 状态CURL 命令访问浏览器访问 高可用验证停止…...

【Linux】IO多路转接——select接口

目录 I/O多路转接之select select初识 select函数 socket就绪条件 select基本工作流程 select服务器 select的优点 select的缺点 select的适用场景 I/O多路转接之select select初识 select是系统提供的一个多路转接接口。 select系统调用可以让我们的程序同时监视多…...

error_Network Error

此页面为订单列表&#xff0c;是混合开发(页面嵌入在客户端中) 此页面为订单列表&#xff0c;此需求在开发时后端先将代码发布在测试环境&#xff0c;我在本地调试时调用的后端接口进行联调没有任何问题。 此后我将代码发布在测试环境&#xff0c;在app中打开页面&#xff0c…...

Python爱心光波

文章目录 前言Turtle入门简单案例入门函数 爱心光波程序设计程序分析 尾声 前言 七夕要来啦&#xff0c;博主在闲暇之余创作了一个爱心光波&#xff0c;感兴趣的小伙伴们快来看看吧&#xff01; Turtle入门 Turtle 是一个简单而直观的绘图工具&#xff0c;它可以帮助你通过简…...

【分布式】Viewstamped Replication Revisited

篇前感悟&#xff1a; 阅读分布式系统文章的意义其实并不在于你个人真正地去开发这样一个基于这种协议的系统&#xff0c;因为真正去开发一个高可用的分布式系统实在是太难了&#xff08;对我来说…&#xff09;更多的还是汲取其中的思想&#xff0c;包括设计思路&#xff0c;优…...

微服务07-分布式缓存

前提: 单机的Redis存在四大问题: 解决办法:基于Redis集群解决单机Redis存在的问题 1、Redis持久化 Redis 具有持久化功能,其会按照设置以 快照 或 操作日志 的形式将数据持久化到磁盘。 Redis有两种持久化方案: RDB持久化AOF持久化注意: RDB 是默认持久化方式,但 Red…...

QGraphicsView放大时,paint有时不被调用,导致图像绘制不出来(2)

此前&#xff08;1&#xff09;解决的是在QGraphicsItem::boundingRect不变的情况下造成不绘制。这次解决的是QGraphicsItem::boundingRect随时都发生变化导致的不绘制。 这问题是我在不继承QGraphicsLineItem&#xff08;调用setLine&#xff09;&#xff0c;而是继承QGraphic…...

深入理解设计模式-创建型之建造者模式(与工厂区别)

什么是建造者设计模式&#xff1f;和工厂设计模式有什么区别 建造者设计模式&#xff08;Builder Design Pattern&#xff09;和工厂设计模式&#xff08;Factory Design Pattern&#xff09;都是面向对象设计中的创建型模式&#xff0c;但它们解决的问题和应用场景有所不同。…...

Centos7多台服务器免密登录

准备四台服务器: docker0 docker1 docker2 docker3 在docker0服务器上生成公钥和私钥 [rootwww ~]# ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory /root/.ssh. Enter passp…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

智能职业发展系统:AI驱动的职业规划平台技术解析

智能职业发展系统&#xff1a;AI驱动的职业规划平台技术解析 引言&#xff1a;数字时代的职业革命 在当今瞬息万变的就业市场中&#xff0c;传统的职业规划方法已无法满足个人和企业的需求。据统计&#xff0c;全球每年有超过2亿人面临职业转型困境&#xff0c;而企业也因此遭…...