เหตุใดการเลือนหายของภาพเคลื่อนไหวจึงไม่ทำงาน แต่ภาพเคลื่อนไหวเลือนหายไป
ฉันใหม่เพื่อหลามและฉันมากับความคิดนี้ในวิธีที่จะทำให้การเคลื่อนไหวง่าย ๆ จางหายไปในหลามใช้ tkinter และโมดูลเวลา ฉันได้กำหนดแอนิเมชั่นสองแบบสำหรับโปรแกรม: อันหนึ่งเฟดเข้าและอีกอันจะเลือนหายไป ภาพเคลื่อนไหวที่เลือนหายไปทำงานได้อย่างสมบูรณ์แบบและตรงตามที่ฉันต้องการอย่างไรก็ตามการจางหายของภาพเคลื่อนไหวไม่ได้ผลเลย โปรแกรมจะไม่แสดงจนกว่าการวนซ้ำ while จะเสร็จ ฉันทำอะไรผิดหรือเป็นไปไม่ได้ที่จะสร้างเอฟเฟกต์เลือนหายใน python tkinter? นี่คือข้อมูลโค้ดของฉัน:
from tkinter import *
import time
root = Tk()
transparency = 0
while transparency <= 1:
transparency += 0.1
root.wm_attributes("-alpha", transparency)
time.sleep(0.03)
def fade():
t = 1
while t > 0:
t -= 0.1
root.wm_attributes("-alpha", t)
time.sleep(0.03)
root.destroy()
btn = Button(root, text='fade exit', command=fade).pack()
root.mainloop()
คำตอบ
แทนที่จะใช้while
ลูปและtime
ใช้after(millis, function)
และเรียกซ้ำ
โบนัส:
- ใช้อาร์กิวเมนต์ของฟังก์ชันเพื่อปรับแต่งเอฟเฟกต์และพฤติกรรมการจาง
- สิ่งนี้จะไม่บล็อกรูทจากการอัปเดต
- ทุกอย่างถูกห่อหุ้ม
- ฟังก์ชันเหล่านี้สามารถใช้กับ
Toplevel
หน้าต่างใดก็ได้ applyFades
จัดการทุกอย่างในการโทรครั้งเดียว
หากคุณจำเป็นอย่างยิ่งที่จะแนบคุณสมบัติเหล่านี้ไปButton
เพียงแค่กำหนดโต้แย้งเช่นนี้command
command=lambda: fadeOut(root)
window.py
''' Fade In
@window ~ the window to affect
@millis ~ the amount of milliseconds to wait before next recursion
@inc ~ the amount to increment alpha on each recursion
'''
def fadeIn(window, millis:int=50, inc:float=0.1):
alpha = float(window.attributes('-alpha')) + inc
window.attributes('-alpha', alpha)
if alpha < 1:
window.after(millis, lambda: fadeIn(window, millis, inc))
else:
window.attributes('-alpha', 1.0)
''' Fade Out
@window, @millis ~ see: Fade In
@dec ~ the amount to decrement alpha on each recursion
@destroy ~ True|False destroy the window when effect is complete
'''
def fadeOut(window, millis:int=50, dec:float=0.1, destroy:bool=True):
alpha = float(window.attributes('-alpha')) - dec
window.attributes('-alpha', alpha)
if alpha > 0:
window.after(millis, lambda: fadeOut(window, millis, dec, destroy))
else:
window.attributes('-alpha', 0.0)
if destroy:
window.destroy()
''' Assign All Fades In One Call
@window, @millis, @inc ~ see: Fade In
@dec, @destroy ~ see: Fade Out
@close ~ True|False add fadeOut effect to window close button
'''
def applyFades(window, millis:int=50, inc:float=0.1, dec:float=0.1, destroy:bool=True, close:bool=True):
window.attributes('-alpha', 0.0)
window.after(millis, lambda: fadeIn(window, millis, inc))
if close:
window.protocol("WM_DELETE_WINDOW", lambda: fadeOut(window, millis, dec, destroy))
main.py
import tkinter as tk
import window as win
root = tk.Tk()
win.applyFades(root)
root.mainloop()
มาดูกันว่าคุณสคริปต์ทำอะไร ที่จุดเริ่มต้นroot = Tk()จะถูกกำหนดซึ่งเริ่มต้นล่าม tcl / tk และสร้างหน้าต่างรูท จากนั้นจะควบคุมแอตทริบิวต์ความทึบให้จางลงหลังจากนั้นวิดเจ็ตปุ่มจะถูกวางไว้บนหน้าต่างรูทซึ่งมีคุณสมบัติเหล่านี้:
- ข้อความ 'จางทางออก' ถูกเขียนไว้ที่ด้านบนของวิดเจ็ต
- มันรอให้คลิกเมาส์และหลังจากนั้นมันจะควบคุมแอตทริบิวต์ความทึบของหน้าต่างรูทให้เลือนหายไป
สุดท้ายroot.mainloop()คือการใช้แทน
while True:
root.update_idletasks()
root.update()
คุณอาจสนใจว่าปุ่ม 'จางหายไป' กำลังถูกสร้างขึ้นในขณะที่หน้าต่างรูทของคุณไม่ได้รับการอัปเดต นี่เป็นสาเหตุที่คุณไม่สามารถมองเห็นการจางหายไปได้
โซลูชันที่ 1. การอัปเดตหน้าต่างรูทหลังจากแต่ละตัวอย่างของการซีดจางใน:
from tkinter import *
import time
def fade():
t = 1
while t > 0:
t -= 0.1
root.wm_attributes("-alpha", t)
time.sleep(0.03)
root.destroy()
root = Tk()
transparency = 0
btn = Button(root, text='fade in', command=fade)
btn.pack()
while transparency <= 1:
transparency += 0.1
root.wm_attributes("-alpha", transparency)
root.update_idletasks()
root.update()
time.sleep(0.03)
btn.configure(text='fade exit') #I guess no new button is needed and text should be replaced only
root.mainloop()
วิธีแก้ปัญหา 2.เป็นเรื่องปกติที่จะไม่ใช้tkinter
ร่วมกับวิธีการtime
ใช้งาน after
ตรวจสอบคำตอบของ Michael