Python tkinter While True loopu'na girdiğinde yanıt vermiyor

from pynput.keyboard import Key, Controller
import time
import random
import tkinter
window = tkinter.Tk()

keyboard = Controller()

def ClickedButon():
  while True:
      for _ in range(28):
        z = random.randint(1, 3)
        print(z)
        time.sleep(1)
        x = random.randint(1, 2)
        print(x)
        keyboard.type('')
        keyboard.press(Key.enter)
        time.sleep(z)
        keyboard.type('')
        keyboard.press(Key.enter)
        time.sleep(x)
        keyboard.type('')
        keyboard.press(Key.enter)
        time.sleep(14)

        __import__("time").sleep(100)

button=tkinter.Button(window,text="Başlat",command=ClickedButon)
button.pack()

window.mainloop()

While True loopu ve time.sleepten kaynaklanan bir yanıt vermeme hatası galiba çözümlerini buldum fakat kendi kodum üzerinde yapamadım nasıl yapıcam açıklarmısınız?

Öncelikle python bildiğini, kod okuyabildiğini, ingilizce kaynak dahi olsa örnek kodlardan yararlanabileceğini varsayarak yazıyorum. Bunlar uymazsa, yorumumu dikkate alma diğer cevap verecekleri bekle.

Evet, while döngüsü bitmeden buton tepki veremez. Tespitin doğru. Hatta benzer bir konu açtığını aslında çözüm için ipuçları da verildiğini düşünüyorum.

Ne tür çözümler bulduğunu da paylaşırsan koduna nasıl uyarlayacağına bakabiliriz.

Şöyle yapabilirsin. while döngüsünün tamamını bir fonksiyona taşırsan ve bu fonksiyonu da,

multiprocessing — Process-based parallelism — Python 3.10.5 documentation

Gibi yeni bir process başlatarak programın beklemeden devam etmesini sağlayabilirsin.

Yine thread kullanabilirsin.

threading — Thread-based parallelism — Python 3.10.5 documentation

Bu iş için thread daha doğru tercih olmakla beraber (bence) proccess sanki daha kolay öğrenilebilir gibi duruyor.

How to use Thread in Tkinter Python - GeeksforGeeks

Yukarıdaki linkteki örnekleri anlarsan çabucak koduna uygulayabilirsin.

# Import Module
from tkinter import *
import time
from threading import *
  
# Create Object
root = Tk()
  
# Set geometry
root.geometry("400x400")
  
# use threading
  
def threading():
    # Call work function
    t1=Thread(target=work)
    t1.start()
  
# work function
def work():
  
    print("sleep time start")
  
    for i in range(10):
        print(i)
        time.sleep(1)
  
    print("sleep time stop")
  
# Create Button
Button(root,text="Click Me",command = threading).pack()
  
# Execute Tkinter
root.mainloop()

Verdiğim linkin içindeki bu kod parçası bunun nasıl olduğunu gösteriyor.

EDIT:

Aslında şunu da eklemek isterim. while döngüsü ile bu şekilde keyboard girişi almak yerine,

python - How do I disable keyboard input into an Entry widget, disable resizing of tkinter window and hide the console window? - Stack Overflow

Şurada olduğu gibi, belirli bir süre keyboard girişini disabled etmek daha düzgün görünür. Yani sleep boyunca girişleri durduracak şekilde kodlamak daha mantıklı olur.

Nereden girdi aldığını bilemediğinden eğer bir textbox vs ise bunları da sleep boyunca disable etmek daha profesyonel görünebilir.

How to disable an Entry widget in Tkinter? (tutorialspoint.com)

Gibi bir widget i nasıl devre dışı bırakabileceğin/ disable edebileceğin örneğine ulaşabilirsin.

Yine bu işleri sleep yerine bir timer widgeti ile yapmak da daha kolay olabilir.

How to create a timer using tkinter? (tutorialspoint.com)

2 Beğeni

Çok teşekkür ederim bu kadar ayrıntılı ve özenerek yazdığınız için sayenizde yapabildim (:

1 Beğeni

Bu arada program artık exit() komuduyla kapnmıyor , niye ?_?

Thread bitmeden kapanmaz. Kapatmak için ayrıca takibi gerekir.

sonlandırmak için:

Python | Different ways to kill a Thread - GeeksforGeeks

5 Beğeni

Hocam bunun için arkadaşın thread sınıfındaki daemon parametresine True argumanı girmesi yeterli olmaz mı ?

1 Beğeni

Haklısın evet daemon=True yapılabilir.

Ama denemeden emin olamadığım bazı konular var. Thread in durumunu kontrol ettiğimizde yine yavaşlamaya neden olan bir şeyler hatırlıyorum.

threading — Thread-based parallelism — Python 3.10.5 documentation

Linkini daha önce verdim. Orada bu konu zaten açıklanmış.

En baştaki tereddütüm buydu zaten, thread ile ilgili bir çok şeyi anlatmak gerekecek.

Bunlardan biri de daemon flag’i.

Bir haberleşme projesinde bu flag açıkken, threadler beklediğim hızda çalışmadı. Sanki müstakil çalışmak yerine arada thread in durumunu kontrol eden bir şeyler var.

Ama bu projede denenebilir.

Yani öneriniz yerinde ama bende nedense daemon’dan uzak dur aklında olsun diye bir deneyimime dayalı bilgim var aklımda kendim için.

EDIT:

Kendimin Türkçe meali: Daemon açık olduğunda, çalışan threadler kendi başına değil bağımlı gibi davranıp sürekli durumlarının takip edilmesine neden olan bir mekanizmadan doalyı performans uygulamalarında hızda yavaşlamaya neden oldu. Ben de uzak durmaya çalışıyorum.

EDIT 2:

Bu yavaşlama sanırım join() kullandığımda oluşuyordu. Konuyu bulabilirsem onun kodunu da eklemek istiyorum.

Yani doğrudan daemondan mı kaynaklı, join() den mi kaynaklı hatırlayamadım.

1 Beğeni