So Im running everything on threads and the run
and not run
works as intended but running
doesnt print, I tried calling it in
status["text"]="Working"
print("run")
autofisher()
but that just freezes up my whole program, I also tried putting in root.after
on the end but still freezes everything up. Any way here is the snippet of the part im talking about.
def keyStart():
global run
run = True
while run == True:
status["text"]="Working"
print("run")
autofisher()
def keyStop():
global run
run = False
if run == False:
status["text"]="Not Working"
print("not run")
buttonStart = Button(root, text="Start", command=keyStart)
buttonStart.grid(columnspan=1, column=0, row=3)
buttonStop = Button(root, text="Stop", command=keyStop)
buttonStop.grid(columnspan=1, column=1, row=3)
def autofisher():
global run
while run == True:
print("running")
And im not sure if its needed but here is also the full script(Yes I know its messy, its my first script and a lot of things I wanted didnt work as I wanted and ended up commenting them out for later, also I know its a very bad tkinter implementation because it was just a script before and decided after that I wanted to make a full gui, so please just ignore those if there is an actual way to fix the problem of this topic unless the problem is being caused by how I implemented the gui)
import pyautogui
import time
import keyboard
from pywinauto.application import Application
import tkinter as tk
import threading
from tkinter.ttk import *
root = tk.Tk()
root.title('Fisher Version 1.0')
canvas = tk.Canvas(root, width=150, height=100)
canvas.grid(columnspan=2)
#Title
titleLabel = tk.Label(root, text="Fisher Version 1.0") #Title key label
titleLabel.grid(columnspan=2, column=0, row=0)
#Status
status = tk.Label(root, text="Not Working")
status.grid(columnspan=2, column=0, row=1)
#Hot Key for run/stop
hotkeyLabel = tk.Label(root, text="Key for start/stop") #Hot key label
hotkeyLabel.grid(columnspan=1, column=0, row=2)
"""
keysHotStart = ['z','b','n','q'] #Combo Box ROd
hotComboStart = Combobox(root, value=keysHotStart, width=10, state="readonly")
hotComboStart.grid(columnspan=1, column=0, row=3)
hotComboStart.current(0)
keysHotStop = ['z','b','n','q'] #Combo Box ROd
hotComboStop = Combobox(root, value=keysHotStop, width=10, state="readonly")
hotComboStop.grid(columnspan=1, column=1, row=3)
hotComboStop.current(2)
"""
#Hot key for Rod
rodkeyLabel = tk.Label(root, text="Key for Rod") #Hot key rod
rodkeyLabel.grid(columnspan=2, column=0, row=4)
keysRod = ['1','2','3','4', '5']
rodCombo = Combobox(root, value=keysRod, width=10, state="readonly")
rodCombo.grid(columnspan=2, column=0, row=5)
rodCombo.current(0)
#Hot key for food
foodkeyLabel = tk.Label(root, text="Key for Food") #Hot key food
foodkeyLabel.grid(columnspan=2, column=0, row=6)
keysFood = ['1','2','3','4', '5']
foodCombo = Combobox(root, value=keysFood, width=10, state="readonly")
foodCombo.grid(columnspan=2, column=0, row=7)
foodCombo.current(1)
#Hot key for drink
drinkkeyLabel = tk.Label(root, text="Key for Drink") #Hot key drink
drinkkeyLabel.grid(columnspan=2, column=0, row=8)
keysDrink = ['1','2','3','4', '5']
drinkCombo = Combobox(root, value=keysDrink, width=10, state="readonly")
drinkCombo.grid(columnspan=2, column=0, row=9)
drinkCombo.current(2)
app = Application().connect(title_re="FiveM")
win = app.window(title_re="FiveM")
run = False
def keyStart():
global run
run = True
if run == True:
status["text"]="Working"
print("run")
def keyStop():
global run
run = False
if run == False:
status["text"]="Not Working"
print("not run")
buttonStart = Button(root, text="Start", command=keyStart)
buttonStart.grid(columnspan=1, column=0, row=3)
buttonStop = Button(root, text="Stop", command=keyStop)
buttonStop.grid(columnspan=1, column=1, row=3)
def autofisher():
global run
while run == True:
print("running")
#This checks if the G prompt shows up so it can be pressed
if pyautogui.locateOnScreen('pressg.png', region=(305, 23, 30, 30), grayscale=False, confidence=0.7) != None:
win.send_keystrokes('g')
time.sleep(1)
#This checks if the fish is ready to be caught
r, g, b = pyautogui.pixel(959, 337) # detects the green zone
a, c, d = pyautogui.pixel(959, 340)
if 100 <= r <= 110 and 145 <= g <= 155 and 0 <= b <= 5: # detects if in green is showing
#This detects when to press e to catch the fish
for y in range(338, 350, 1): # detects if line in range
j, k, l = pyautogui.pixel(959, y)
if 0 <= k <= 50 and 0 <= k <= 50:
win.send_keystrokes('e')
if pyautogui.locateOnScreen('bait.png', region=(1665,516,245,45), grayscale=False, confidence=0.7) != None:
time.sleep(20)
win.send_keystrokes(rodCombo.get())
stats()
time.sleep(1)
def stats():
q, w, e = pyautogui.pixel(209, 1042) # detects the hunger
if 55 <= q <= 70 and 55 <= w <= 70 and 55 <= e <= 70:
# press 3 for food
win.send_keystrokes(foodCombo.get())
time.sleep(12)
u, i, o = pyautogui.pixel(287, 1056) # detects the thirst
if 55 <= u <= 70 and 55 <= i <= 70 and 55 <= o <= 70:
win.send_keystrokes(drinkCombo.get())
time.sleep(12)
def starts():
autofisherT = threading.Thread(target=autofisher)
statsT = threading.Thread(target=stats)
#pressT = threading.Thread(target=press)
keyStartT = threading.Thread(target=keyStart)
keyStopT = threading.Thread(target=keyStop)
#notificationT = threading.Thread(target=notification)
statsT.start()
#notificationT.start()
keyStartT.start()
keyStopT.start()
autofisherT.start()
#pressT.start()
starts()
root.mainloop()
CodePudding user response:
Tkinter, like all GUI frameworks, is event driven. Your GUI calls don't actually do any drawing. They just sent messages. There is a main loop (root.mainloop
) that fetches and dispatches messages for processing. As long as a message handler is running, it can't get back to the main loop, and no more messages will be handled.
That's the issue here. Your button press will trigger your keystart
, which calls autofisher
, and autofisher
never returns. It runs a 100% tight CPU loop. Because you are not getting back to the main loop, the GUI is frozen. No more activity will be handled.
You shouldn't be mixing tkinter
and keyboard
. tkinter
has its own keyboard handling ability that plays nicely with the rest of the framework. You need to throw out the keyboard
module, and use tkinter
bind
calls to associate callbacks with keystrokes.
https://python-course.eu/tkinter/events-and-binds-in-tkinter.php https://www.pythontutorial.net/tkinter/tkinter-event-binding/