简体   繁体   中英

Tkinter button does not appear, sorry guys I know that a thread already exists

The button it does not appear, any tips guys?. The screenshot func works fine but not the button, I have to close it on my own.

import time
from tkinter import *
import pyautogui

class App:

    def __init__(self, master, task):

        frame = Frame(master)
        frame.pack()

        self.button = Button(
            frame, text="QUIT", fg="red", command=frame.quit
            )
        self.button.pack(side=LEFT)
        frame.after(0,task)

def task():
    i = 1
    while i > 0:
        myScreenshot = pyautogui.screenshot()
        myScreenshot.save(r"C:\Users\elsin\Desktop\python\nameTask" + str(i) + ".png")
        time.sleep(2)
        i += 1

root = Tk()

app = App(root,task())
root.mainloop()

Error:

C:\Users\elsin\PycharmProjects\pythonProject\venv\Scripts\python.exe C:/Users/elsin/PycharmProjects/pythonProject/1.py
Traceback (most recent call last):
  File "C:\Users\elsin\PycharmProjects\pythonProject\1.py", line 28, in <module>
    app = App(root,task())
  File "C:\Users\elsin\PycharmProjects\pythonProject\1.py", line 23, in task
    time.sleep(2)
KeyboardInterrupt

Process finished with exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)

First: you have to send function's name without () .

At this moment you have something like

result = task()

app = App(root, result)

but task() runs while -loop which runs all time and code never goes to line App(root, result) - so it can't display it.

If you send function's name then you will have another problem - your frame.after(0, task) starts this task at once and it blocks rest of code.

If you use some delay frame.after(100, task) then it will have time to display window with button.

But it still have problem with task which runs while -loop and it blocks mainloop and tkinter` is freezed.


The main problem is that you have two loops which have to work at the same time:

  • first: mainloop() ,
  • second: while -loop

and this need to run one of them in separated thread, or you have to use root.after(2000, task) instead of while + sleep()

BTW: you should use master.destroy instead of frame.quit to stop tkinter program

import time
import tkinter as tk  # PEP8: `import *` is not preferred
import pyautogui

class App:

    def __init__(self, master, task):

        frame = tk.Frame(master)
        frame.pack()

        self.button = tk.Button(frame, text="QUIT", fg="red", command=master.destroy)
        self.button.pack(side='left')
        
        frame.after(100, task, 1)

def task(i):
    myScreenshot = pyautogui.screenshot()
    myScreenshot.save(r"C:\Users\elsin\Desktop\python\nameTask" + str(i) + ".png")
    i += 1
    root.after(2000, task, i)

root = tk.Tk()
app = App(root, task)
root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM