0

I'm tinkering with Tkinter and trying to check if my program is open on pressing a button, but the Tkinter is not updating my label. Why?

from win32gui import GetWindowRect, FindWindow
from tkinter import Tk, ttk, BooleanVar

class Bot:
    root        = Tk()
    is_gta_open = BooleanVar(None, False)

    def mta_open_string(self):
        return "włączone" if self.is_gta_open.get() else "wyłączone"

    def draw_gui(self):
        frame = ttk.Frame(self.root, padding=10)
        frame.grid()

        ttk.Label(frame, text=f"Status gry: {self.mta_open_string()}").grid(column=0, row=0)
        ttk.Button(frame, text="Odśwież", command=lambda: [self.try_finding_rect(), self.root.update()]).grid(column=1, row=0)

        self.root.mainloop()

    def try_finding_rect(self):
        window_handle = FindWindow("Grand theft auto San Andreas", None)
        
        if window_handle == 0:
            self.is_gta_open.set(False)
            return

        self.is_gta_open.set(True)

    def run(self):
        self.try_finding_rect()
        self.draw_gui()

if __name__ == "__main__":
    Bot().run()

I'm updating the state using self.root.update method and using BooleanVar, so I don't know why this is not working.

2
  • No, this does not changed anything. :( Commented Jan 2, 2023 at 20:40
  • But there are no errors. Commented Jan 2, 2023 at 20:44

2 Answers 2

1

I've put together a very minimal example app that should work as intended. I don't have a copy of GTA to test with so I used a different app, but it should function the same way with any app in principle:

import tkinter as tk
import ctypes
from tkinter import ttk


class Bot(tk.Tk):  # init Tk
    def __init__(self):
         super.__init___()
         APP_NAME = 'Grand theft auto San Andreas'
         self.status_label = tk.Label(self, text='Press the button')
         self.status_label.pack()
         self.run_btn = ttk.Button(
             self,
             text='Click Me!',
             command=lambda: self.check_for_app(APP_NAME)
        )
        self.run_btn.pack()
    
    def check_for_app(app_name: str):
        user32 = ctypes.WinDLL('user32')
        if user32.FindWindowW(None, app_name):
            self.status_label.config(text='Running')
        else:
            self.status_label.config(text='Not Running')


if __name__ == '__main__':
    app = Bot()
    app.mainloop()
Sign up to request clarification or add additional context in comments.

Comments

1

Updating a variable won't change an f-string that uses the variable. You must explicitly configure the widget to show the new value.

To do that you'll need to keep a reference to the label widget, and then update the widget with the configure method.

def draw_gui(self):
    ...    
    self.status_label = ttk.Label(frame, text=f"Status gry: {self.mta_open_string()}")
    self.status_label.grid(column=0, row=0)
    ...

def try_finding_rect(self):
    ...
    self.is_gta_open.set(True)
    self.status_label.configure(text=f"Status gry: {self.mta_open_string()}")

Personally I recommend using a proper method for the button rather than a complicated lambda. That will make the code easier to read and easier to debug.

For example:

def draw_gui(self):
    ...
    ttk.Button(frame, text="Odśwież", command=self.update_status)
    ...

def update_status(self):
    self.try_finding_rect(), 
    self.status_label.configure(text=f"Status gry: {self.mta_open_string()}")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.