Python Forum
[Tkinter] Sections of the code causes the GUI to freeze. What should I do?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Sections of the code causes the GUI to freeze. What should I do?
#11
Care to enlighten about the cause of the problem? I have no lag in the mouse curser when the listener is running, but I am not calling the pyautogui function. Is locateCenterOnScreen() really slow? You could run your click code in a separate thread to keep the mouse responsive.

This code runs the click code in its own thread, so it doesn't bog down the mouse. I use sleep(1) to simulate some slow code that would block the mouse from moving,
from pynput.mouse import Listener
import tkinter as tk
import threading
from time import sleep


def on_click_worker(x1, y1):
    """The slow code you want to run each time you click the mouse."""
    sleep(1)  # Simulates slow code
    print(x1, y1)  # replace with your image finding/process killing code


def on_click(x1, y1, button, pressed):
    """Mouse listener event handler.  Return False to stop listener."""
    if window.winfo_containing(x1, y1) in (start_btn, exit_btn):
        # Stop listener if user clicks start or exit buttons
        return False
    if pressed:
        threading.Thread(target=on_click_worker, args=(x1, y1)).start()
    return True


def mouse_listener():
    """Worker function for mouse listener thread"""
    with Listener(on_click=on_click) as listener:
        listener.join()


def start_stop():
    """Start/Stop button callback"""
    if start_btn["text"] == "Start":
        start_btn["text"] = "Stop"
        threading.Thread(target=mouse_listener).start()
    else:
        start_btn["text"] = "Start"


def exit_program():
    """Exit button callback"""
    window.quit()


font = ("Helvetica", 24)
window = tk.Tk()

start_btn = tk.Button(window, text="Start", font=font, width=5, command=start_stop)
start_btn.pack(side=tk.LEFT, ipadx=20, ipady=20)

exit_btn = tk.Button(window, text="Exit", font=font, command=exit_program)
exit_btn.pack(side=tk.LEFT, ipadx=20, ipady=20)

window.mainloop()
Reply
#12
Yes it appears that pyautogui with locateCenterOnScreen and
if pressed and (icon_pos := locateCenterOnScreen("loot_icon.png", confidence=0.9)):
            x2, y2 = icon_pos
            if -30 < x2 - x1 < 30 and -42 < y2 - y1 < 42:
                print("Image at: {}".format((x2, y2)))
                print("Cursor at: {}".format((x1, y1)))
                for proc in psutil.process_iter():
                    if proc.name() == "LeagueClient.exe":
                        proc.kill()
appears to be slow and causes mouse lag. With single click its not that big of a deal I guess? But often mouse clicking is quite bad. Tried to put it into new thread like you adviced but I dont think that anything really changed

def on_click_worker(x1, y1, pressed):
    """The slow code you want to run each time you click the mouse."""
    if pressed and (icon_pos := locateCenterOnScreen("loot_icon.png", confidence=0.9)):
            x2, y2 = icon_pos
            if -30 < x2 - x1 < 30 and -42 < y2 - y1 < 42:
                print("Image at: {}".format((x2, y2)))
                print("Cursor at: {}".format((x1, y1)))
                for proc in psutil.process_iter():
                    if proc.name() == "LeagueClient.exe":
                        proc.kill()

def on_click(x1, y1, button, pressed):
    """Mouse listener event handler.  Return False to stop listener."""
    if window.winfo_containing(x1, y1) in (start_btn, exit_btn):
        # Stop listener if user clicks start or exit buttons
        return False
    if pressed:
        threading.Thread(target=on_click_worker, args=(x1, y1)).start()
        
    return True
Reply
#13
Maybe you could run this part as a subprocess
            x2, y2 = icon_pos
            if -30 < x2 - x1 < 30 and -42 < y2 - y1 < 42:
                print("Image at: {}".format((x2, y2)))
                print("Cursor at: {}".format((x1, y1)))
                for proc in psutil.process_iter():
                    if proc.name() == "LeagueClient.exe":
                        proc.kill()
You could write it as a shell script or a python program that takes x1, y1 as arguments, does the image search and the process stuff. Your python program runs the script. This example runs a python script.
def on_click(x1, y1, button, pressed):
    """Mouse listener event handler.  Return False to stop listener."""
    if window.winfo_containing(x1, y1) in (start_btn, exit_btn):
        # Stop listener if user clicks start or exit buttons
        return False
    if pressed:
        subprocess.Popen(['python', 'script_name.py', str(x1), str(y1)])
Reply
#14
Im not quite sure if this will work for me since later I'd like to convert all of that into an windows exe app. I can try it tho
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] mpv window freeze before video end rfeyer 7 3,374 Feb-20-2021, 09:34 PM
Last Post: rfeyer
  [Tkinter] tkinter freeze DeanAseraf1 0 2,090 Jul-20-2019, 07:46 AM
Last Post: DeanAseraf1
  Tkinter GUI freeze petterg 4 10,833 Jul-01-2019, 03:54 PM
Last Post: petterg
  [Tkinter] GUI Freeze/tkinter SamGer 2 4,061 Jun-24-2019, 07:25 PM
Last Post: noisefloor

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020