You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CustomTkinter中输入YouTube链接后更新Label内容

解决YouTube下载器UI自动更新问题

你的问题出在无限while循环上——它在root.mainloop()执行前就占据了主线程,导致UI事件循环根本无法启动,程序自然卡死。Tkinter系框架(包括CustomTkinter)的UI更新依赖主事件循环,不能用死循环阻塞主线程。

下面是可行的解决方案:

核心思路

  • 用Entry内容变化事件监听输入,替代轮询逻辑
  • 网络请求(获取YouTube视频信息)放在子线程中,避免阻塞UI
  • 通过root.after()在主线程更新UI(子线程不能直接操作Tkinter控件)

修改后的主程序代码

import customtkinter as tk
from pytube import YouTube
import threading

root = tk.CTk()
root.geometry('690x700')
root.title('YouTube to Video Converter')
tk.set_appearance_mode('System')
tk.set_default_color_theme('YT_Downloader/theme.json')

# 初始化默认视频
default_url = 'https://www.youtube.com/watch?v=7yn-0-1GIrk'
current_yt = YouTube(default_url)

frame = tk.CTkFrame(master=root, corner_radius=10)
frame.grid(row=0, column=0, padx=20, pady=20)

title = tk.CTkLabel(frame, text='YouTube to Video Converter', font=('Roboto', 50))
title.grid(row=1, column=0, columnspan=3, pady=10, padx=12, sticky='nsew')

url = tk.CTkEntry(frame, placeholder_text=default_url, font=('Roboto', 12), width=250, height=20)
url.grid(row=3, column=2, columnspan=2, padx=10, pady=12)

video_name = tk.CTkLabel(frame, text=f'Title: {current_yt.title}', font=('Roboto', 18))
video_name.grid(row=2, column=0, columnspan=2, padx=5)

video_views = tk.CTkLabel(frame, text=f'Views: {current_yt.views}', font=('Roboto', 18))
video_views.grid(row=3, column=0, columnspan=2, padx=5)

def update_video_info(new_url):
    """子线程中获取视频信息,再通知主线程更新UI"""
    try:
        yt = YouTube(new_url.strip())
        # 通过after回到主线程更新UI
        root.after(0, lambda: video_name.config(text=f'Title: {yt.title}'))
        root.after(0, lambda: video_views.config(text=f'Views: {yt.views}'))
        global current_yt
        current_yt = yt
    except Exception:
        # 处理无效URL的情况
        root.after(0, lambda: video_name.config(text='Title: 无效URL'))
        root.after(0, lambda: video_views.config(text='Views: --'))

def on_url_change(event):
    """监听Entry内容变化,触发信息更新"""
    input_url = url.get()
    if not input_url:
        # 输入为空时用默认URL
        threading.Thread(target=update_video_info, args=(default_url,), daemon=True).start()
    else:
        threading.Thread(target=update_video_info, args=(input_url,), daemon=True).start()

def egt():
    print(url.get())
    # 调用下载逻辑,同样用线程避免阻塞UI
    from script import Process
    threading.Thread(target=Process, args=(current_yt,), daemon=True).start()

enter_url = tk.CTkLabel(frame, text='Please Insert your URL in the Box Below', font=('Roboto', 18))
enter_url.grid(row=2, column=2, columnspan=2, padx=5)

button = tk.CTkButton(frame, text='Convert', font=('roboto', 18), command=egt )
button.grid(row=5, column=2)

# 绑定Entry的按键释放事件
url.bind('<KeyRelease>', on_url_change)

root.mainloop()

修改后的Script.py代码

from pytube import YouTube

def Process(yt):
    try:
        stream = yt.streams.get_highest_resolution()
        stream.download('YT_Downloader/videos')
    except Exception as e:
        print(f"下载出错: {str(e)}")

关键说明

  1. 移除死循环:用url.bind('<KeyRelease>', on_url_change)监听输入变化,用户每输入一个字符就触发一次检查
  2. 线程处理网络请求:创建YouTube对象需要网络请求,放在子线程中避免UI冻结
  3. 安全更新UI:子线程不能直接修改Tkinter控件,必须用root.after(0, 回调函数)回到主线程更新
  4. 错误处理:添加无效URL的提示,避免程序崩溃

内容的提问来源于stack exchange,提问作者Brady

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:05:16