Neden animasyonda solma çalışmıyor ama yavaş yavaş solma animasyonu çalışıyor?

Aug 18 2020

Python'da yeniyim ve tkinter ve zaman modülünü kullanarak python'da nasıl basit bir solma animasyonu yapılacağına dair bir fikir buldum . Program için iki animasyon tanımladım: biri yavaşlamak ve diğeri kaybolmak için. Fade out animasyonu mükemmel ve tam olarak istediğim gibi çalışıyor, ancak animasyondaki solma hiç çalışmıyor. Program, while döngüsü bitene kadar hemen hemen görünmez. Yanlış bir şey mi yapıyorum yoksa python tkinter'da etkili bir solma yaratmak imkansız mı? İşte kod pasajım:

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

Yanıtlar

2 MichaelGuidry Aug 18 2020 at 03:28

whileDöngüler ve kullanmak yerine ve özyinelemeyi timekullanın after(millis, function).

ikramiyeler:

  • solma efektini ve davranışını özelleştirmek için işlev bağımsız değişkenlerini kullanın
  • bu, kökün güncellenmesini engellemeyecektir
  • her şey kapsüllendi
  • bu işlevler herhangi bir Toplevelpencerede kullanılabilir
  • applyFades her şeyi tek bir aramada yönetir

Kesinlikle bir bu özellikleri eklemek gerekirse Button, sadece atamak commandböyle argüman: 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()
2 mathfux Aug 18 2020 at 03:34

Bakalım senaryonuz ne yapıyor. Başlangıçta, root = Tk()bir tcl / tk yorumlayıcısını başlatan ve bir kök penceresi oluşturan atanır. Daha sonra, onun opaklık özelliğini kontrol eder. Bundan sonra, kök pencereye şu özelliklere sahip bir Düğme widget'ı yerleştirilir:

  • widget'ın üst kısmına bir 'soluk çıkış' metni yazılır
  • bir fare tıklaması için bekler ve bir kök pencerenin opaklık özelliğini kontrol ettikten sonra kaybolur.

Son olarak, root.mainloop()yerine geçer

while True:
    root.update_idletasks()
    root.update()

Kök pencereniz güncellenmediği anda 'karartma' düğmesinin oluşturulduğuna dikkat edebilirsiniz. Bu, gerçek solmayı görememenizin bir nedenidir.

Çözüm 1. Her solma örneğinden sonra kök penceresinin güncellenmesi:

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

Çözüm 2. Yöntemle tkinterbirlikte kullanılmaması timeve kullanılması daha normaldir after. Michael'ın cevabına bakın.