Home > Software engineering >  This somehow freezes my whole program and Im not sure why?
This somehow freezes my whole program and Im not sure why?

Time:03-26

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/

  • Related