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.
