R
R
re3r02021-11-14 20:51:44
Python
re3r0, 2021-11-14 20:51:44

How to solve the problem with the visibility of the root variable?

The essence of the script is simply to spam new windows with an image

from random import randint
import tkinter as tk
from PIL import ImageTk, Image
import telebot;
from time import sleep

bot = telebot.TeleBot('token');

def createNewWindow(root, img):
  for i in range(100):
    newWindow = tk.Toplevel(root)
    labelExample = tk.Label(newWindow, image = img)
    w =  randint(0, newWindow.winfo_screenwidth())
    h =  randint(0, newWindow.winfo_screenheight())
    newWindow.geometry('+{}+{}'.format(w, h))
    labelExample.pack()

@bot.message_handler(content_types=['text'])
def get_command(message):
    if message.text == "Start":
      root = tk.Tk()
      img = ImageTk.PhotoImage(Image.open('lol.png'))
      createNewWindow(root, img)
      root.mainloop()
    elif message.text == "Stop":
      root.destroy()
bot.polling(none_stop=True, interval=0)

after the Stop command in the Telegram bot, an error occurs

File "main.py", line 26, in get_command root.destroy
()
UnboundLocalError: local variable 'root' referenced before assignment

archiving in SFX archive windows do not want to close by themselves :/

And if it's not difficult, can you tell me how to loop the script? what would the windows be closed after the Stop command, but it would be possible to start spam again with a stalemate?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vindicar, 2021-11-15
@Vindicar

@bot.message_handler(content_types=['text'])
def get_command(message):
    if message.text == "Start":
      root = tk.Tk()
      img = ImageTk.PhotoImage(Image.open('lol.png'))
      createNewWindow(root, img)
      root.mainloop()
    elif message.text == "Stop":
      root.destroy()

Wow, it's all up and running.
First, if you type Start, then get_command() creates a local root, sets it up, and goes into an infinite loop inside root.mainloop(). I don't know how pytelegrambotapi resolves this, but the bot after this should just stand with a stake until all windows are closed. I suspect that the handler is called in a separate thread, but fz. In any case, you don't have to do this. It is better to have one root that spins inside mainloop () in a separate thread all the time the script is running, and create and delete windows as needed, without creating or killing root.
In general, making a bot friends with a windowed interface is not a trivial task.
Second, the root variable is local. It only exists within the instance of get_command() that was called with the start command. If you call it with the Stop command, you start a separate instance where only the Stop branch is executed - and in this branch root was not declared, it was declared only in the Start branch, in another instance.
Thirdly, windows will only be spammed on the machine where the bot is running. It is, just in case.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question