May-15-2020, 07:59 AM
Good morning,
Right now, im totally confused with tkinter, and the GUI freezing problem ...
First of all, I read this post from Yoritz, and tried to work after it.
What should my program do ?
I've 2 buttons, where I can buy and send adventures in a browsergame.
Since the process behind that ( login, checklogin, buyadv , sendadv ) takes time, I'm working with a ThreadPoolExecutor, so the gui ( shouldnt ) freeze.
I have several problems / missunderstandings right now.
1. why can't I use the thread_pool_executor.submit function directly in the button command ?
Right now I need a not rly needed method for that ( ?! )
2. The Buttons still lock down, so I added the .after() method.
As it seems I do need a new method for that aswell ? Because I need to call the blocking function with that ?
Well. I do not really know how to place the .after() method.
I havent found any good explainations in com,bination with the thread_pool_executor(), which should avoid the gui freezing.
Here is my code. Messy as it is, since it should only be a test, if the gui freezing issue still appears.
(Yes it does )
( Please dont blame me on the imports, maybe wrong method/var names. As mentioned I just wanted to test how, and if the freeze appears.
To simplify the coide underneath here are the methods which cause troubles:
- buyAdventure()
- sendAdventure() // splitted into sendAdventure() and test() for the .after() method ?!
I would even pay someone , to explain that issue to me, if its to much work, to dig through the code for free !
Thanks.
Right now, im totally confused with tkinter, and the GUI freezing problem ...
First of all, I read this post from Yoritz, and tried to work after it.
What should my program do ?
I've 2 buttons, where I can buy and send adventures in a browsergame.
Since the process behind that ( login, checklogin, buyadv , sendadv ) takes time, I'm working with a ThreadPoolExecutor, so the gui ( shouldnt ) freeze.
I have several problems / missunderstandings right now.
1. why can't I use the thread_pool_executor.submit function directly in the button command ?
Right now I need a not rly needed method for that ( ?! )
2. The Buttons still lock down, so I added the .after() method.
As it seems I do need a new method for that aswell ? Because I need to call the blocking function with that ?
Well. I do not really know how to place the .after() method.
I havent found any good explainations in com,bination with the thread_pool_executor(), which should avoid the gui freezing.
Here is my code. Messy as it is, since it should only be a test, if the gui freezing issue still appears.
(Yes it does )
( Please dont blame me on the imports, maybe wrong method/var names. As mentioned I just wanted to test how, and if the freeze appears.
To simplify the coide underneath here are the methods which cause troubles:
- buyAdventure()
- sendAdventure() // splitted into sendAdventure() and test() for the .after() method ?!
import time import tkinter as tk import requests from bs4 import BeautifulSoup from concurrent import futures import time import logging import re thread_pool_executor = futures.ThreadPoolExecutor(max_workers=3) # create logger logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # create file handler file_handler = logging.FileHandler('user/log.log') file_handler.setLevel(logging.INFO) # create console handler stream_handler = logging.StreamHandler() stream_handler.setLevel(logging.ERROR) # create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') file_handler.setFormatter(formatter) stream_handler.setFormatter(formatter) # add the handlers to the logger logger.addHandler(file_handler) logger.addHandler(stream_handler) class TTWarsBot(tk.Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) app.title('TTWarsBot') app.geometry('500x400') self.session = requests.Session() username = 'Fre3k1' password = '1324' BASE_URL = 'https://vip4.ttwars.com/' self.login(username, password, BASE_URL) self.userLabel = tk.Label(self, text=username) self.userLabel.pack() self.passLabel = tk.Label(self, text=password) self.passLabel.pack() self.gameworldLabel = tk.Label(self, text=BASE_URL) self.gameworldLabel.pack() # why cant I just use the thread_pool_executer in the command ? self.buyAdventureButton = tk.Button(self, text='buy adventure', command=lambda: self.on_button(1)).pack(pady=15) self.sendAdventureButton = tk.Button(self, text='send adventure', command=self.on_button_2).pack(pady=15) self.pack() def checkLoginStatus(self, gameworld): logger.info('CALL checkLoginStatus()') html = self.sendRequest(gameworld+"dorf1.php") try: #check GoldAmount parsedHtml = BeautifulSoup(html.content, 'html.parser') checkGold = parsedHtml.find('span', {'class':'ajaxReplaceableGoldAmount'}).text.strip() print(checkGold) if checkGold: self.loggedIn = True logger.info(' checkLoginStatus: LOGGED IN') return True else: return False except: self.loggedIn = False logger.info(' checkLoginStatus: NOT LOGGED IN') return False def login(self, username, password, gameworld): #check Login Status if self.checkLoginStatus(gameworld): logger.info(' STATUS: ALREADY LOGGED IN') else: print(gameworld) logger.info(' RUN login script') html = self.sendRequest('https://vip4.ttwars.com/') parsedHtml = BeautifulSoup(html.content, 'html.parser') s1 = parsedHtml.find('button', {'name':'s1'})['value'] login = parsedHtml.find('input', {'name':"login"})['value'] # Login post request data = {'user' : username, 'pw' : password, 's1' : s1,'w' : "1920:1080", 'login' : login} #html = self.sendRequest(self.config['server'] + 'dorf1.php', data) html = self.sendRequest((gameworld+'dorf1.php'), data) # ??!! why the hell i need to create 2 useless methods for the thread_pool_executor ? def on_button(self,amount): thread_pool_executor.submit(self.buyAdventure(amount)) def on_button_2(self): thread_pool_executor.submit(self.sendAdventure()) def buyAdventure(self, amount): print('buyADV method CALL') counter = 0 advUrl = "https://vip4.ttwars.com/ajax.php?cmd=premiumFeature" adventureHtml = self.sendRequest("https://vip4.ttwars.com/hero.php?t=3") parsedHtml = BeautifulSoup(adventureHtml.content, 'html.parser') ajaxToken = re.search("window.ajaxToken = '(.*)'", str(parsedHtml)).group(1) #with open('user/content.txt', 'w', encoding="utf-8") as f: # f.write(adventureHtml.text) data = {"cmd":"premiumFeature", "featureKey":"buyAdventure", "context":"ExtraModules", "ajaxToken":ajaxToken } while counter < amount: counter += 1 request = self.sendRequest(advUrl, data) # here is a blocking code which takes as long as many adventures I have. # I call test() with the .after method ?! ( not sure if this is even done correctly. guess not, since the gui keeps freezing ) def sendAdventure(self): self.after(0, self.test) def test(self): advUrl = "https://vip4.ttwars.com/hero.php?t=3" advHtml = self.sendRequest(advUrl) parsedHtml = BeautifulSoup(advHtml.content, 'html.parser') # get adventureId's for x in parsedHtml.find_all('a', {'class':'gotoAdventure arrow'}): print("total adventure's: xxx") # adventures will only be updated, if you refresh the webpage. it wont be update when you send a normal request ! # print("current available adventures: " + (int(self.checkAdventure())-1) href = x['href'] kid = href.split("=")[-1] # create data for post request data = {"skip":"1", "from":"list","kid":kid} url = "https://vip4.ttwars.com/"+ href response = self.sendRequest(url, data) time.sleep(2.1) # ================= sendRequest() =============== def sendRequest(self, url, data={}): headers= { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0", "Connection": "keep-alive" } try: if len(data) == 0: # this is a GET request print('GET-REQUEST') html = self.session.get(url, headers=headers) return html else: # this is a POST request print('POST-REQUEST') html = self.session.post(url, headers=headers, data=data) return html except: logger.warning('Request could not be sent ! check url -> '+url) return False # ================= END of sendRequest() ================= if __name__ == '__main__': app = tk.Tk() main_frame = TTWarsBot() app.mainloop()Well. Hopefully someone can explain that to me, or give me any hints ?
I would even pay someone , to explain that issue to me, if its to much work, to dig through the code for free !
Thanks.