simple window with an enter field - python

i'm a new programmer and there are certainly several errors but this shouldn't be difficult to spot. I need to create a simple window with a field named "Concorrente 1:" and an entry field displayed by function named lacopertina(). I don't understand where is the error:
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
from tkinter import ttk
class schermoiniziale(tk.Frame):
def lacopertina():
print(gio1)
#return (tot1)
def __init__(self):
global gio1
#tot1=0
#schermo1=Tk()
self.gio1=tk.StringVar()
lab1=ttk.Label(self, text="Concorrente 1:")
lab1.pack()
ent1=ttk.Entry(self, textvariable=self.gio1)
ent1.pack()
pulsante = ttk.Button(self, text="Inizio", textvariable=self.gio1, command=self.lacopertina)
pulsante.pack()
def main():
schermoiniziale().mainloop()
if __name__== "__main__":
main()

I would suggest you to go through some tutorials on Python OOP.
I have modified your code as below with some comment:
# avoid using wildcard import
import tkinter as tk
from tkinter import ttk
class schermoiniziale(tk.Frame):
def __init__(self, master, **kw):
# need to call __init__() of inherited class
super().__init__(master, **kw)
self.gio1 = tk.StringVar()
lab1 = ttk.Label(self, text="Concorrente 1:")
lab1.pack()
ent1 = ttk.Entry(self, textvariable=self.gio1)
ent1.pack()
# removed textvariable=self.gio1 as I think you actually don't need it
pulsante = ttk.Button(self, text="Inizio", command=self.lacopertina)
pulsante.pack()
def lacopertina(self):
# use .get() to get the content of a StringVar
print(self.gio1.get())
def main():
# need to create the root window before creating other widget
root = tk.Tk()
# pass root window as the parent of the widget
frame = schermoiniziale(root)
frame.pack()
# start the tkinter mainloop
root.mainloop()
if __name__== "__main__":
main()

Related

python custom tkinter widgets don't appear in the window

I'm trying to create a sample GUI using tkinter with customtkinter module ,but nothing appears in the window.
import tkinter
import tkinter.messagebox
import customtkinter
customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("green")
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# configure window
self.title("Tracking System")
self.geometry("350x500")
self.resizable(False,False) # to disable the minimize/maximize buttons.
self.checkbox_slider_frame = customtkinter.CTkFrame(self)
self.switch = customtkinter.CTkSwitch(master=self.checkbox_slider_frame, command=lambda: print("switch 1 toggle"))
self.switch.grid(row=0, column=0)
self.switch.select()
self.button = customtkinter.CTkButton(master=self.checkbox_slider_frame, text="CTkButton")
self.button.grid(row=1 , column = 1)
if __name__ == "__main__":
app = App()
app.mainloop()
I looked into the customtkinter example:-
https://github.com/TomSchimansky/CustomTkinter/blob/master/examples/complex_example.py
But I
You forgot to add self.checkbox_slider_frame to a geometry manager (pack, place, or grid)
self.checkbox_slider_frame = customtkinter.CTkFrame(self)
self.checkbox_slider_frame.pack(expand=True, fill=tkinter.BOTH)

Tkinter not updating when changing variables

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.
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()
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()}")

second window run first how to stop it

when i run python file kill_app its run first 2nd python file(Hb_test.py) then run 1st python on tkinter.i am using vs code and python version is 3.10
see the code below
from tkinter import*
from Lab.Hb_Test import Hba
class kill_App:
def __init__(self,root):
self.root = root
self.root.geometry("1350x700+0+0")
self.root.title("Billing Software")
bg_color = "#074463"
title = Label(self.root,text = "PATHOLAB",bd=12,relief=GROOVE,bg=bg_color,fg="white",
font = ("ALGERIAN",40),pady=2).pack(fill=X)
if __name__=="__main__":
root =Tk()
obj = kill_App(root)
root.mainloop()
****
this is my second
**
**from tkinter import*
from tkinter import ttk
class Hba:
def __init__(self,root):
self.root = root
self.root.geometry("300x70+200+200")
self.root.title("JIBAN PRABHA PATHOLAB")
bg_color = "#074463"
Hb = LabelFrame(self.root,text="BLOOD TEST",font=("ALGERIAN",15,"bold")
,fg="gold",bg=bg_color)
Hb.place(x=0,y=0)
self.hb_neu_lbl = Label(Hb,text="Hb%(sahils) Test",bg=bg_color,fg="white",font=("Bell MT",15,"bold")).grid(row=1,column=1,padx=5,pady=5)
self.hb_neu=Entry(Hb,width=10,font="BellMT 15",bd=5,relief=SUNKEN).grid(row=1,column=2,padx=5,pady=5)
root = Tk()
obj = Hba(root)
root.mainloop()**
**
When Hb_Test is imported, its code will be executed, so the last three lines in the module will create a window:
Hb_Test.py
...
# below lines will create a window
root = Tk()
obj = Hba(root)
root.mainloop()
Note that it is not recommended to create more than one instance of Tk() and execute .mainloop() more than once.
For window other than the main/root window, use Toplevel instead of Tk. For your case, I would suggest that Hba inherits from Toplevel:
import tkinter as tk
class Hba(tk.Toplevel):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.geometry("300x70+200+200")
self.title("JIBAN PRABHA PATHOLAB")
bg_color = "#074463"
Hb = tk.LabelFrame(self, text="BLOOD TEST", font=("ALGERIAN",15,"bold"), fg="gold", bg=bg_color)
Hb.place(x=0, y=0)
self.hb_neu_lbl = tk.Label(Hb, text="Hb%(sahils) Test", bg=bg_color, fg="white", font=("Bell MT",15,"bold"))
self.hb_neu_lbl.grid(row=1,column=1,padx=5,pady=5)
self.hb_neu = tk.Entry(Hb, width=10, font="BellMT 15", bd=5, relief=tk.SUNKEN)
self.hb_neu.grid(row=1,column=2,padx=5,pady=5)
Note that I have changed from tkinter import * to import tkinter as tk because wildcard import is not recommended as well.
Also don't write code like below:
self.hb_neu_lbl = Label(Hb,text="Hb%(sahils) Test",bg=bg_color,fg="white",font=("Bell MT",15,"bold")).grid(row=1,column=1,padx=5,pady=5)
because self.hb_neu_lbl will be None (result of .grid(...)). Code like below instead:
self.hb_neu_lbl = Label(Hb, text="Hb%(sahils) Test", bg=bg_color, fg="white", font=("Bell MT",15,"bold"))
self.hb_neu_lbl.grid(row=1,column=1,padx=5,pady=5)

Using python class with tkinter

From what I read, it is best practice to wrap code for a GUI in a class. How do I do this? I have come up with the following code based on some examples I have looked at, but this does not work as apparently DropdownMenu isn't defined? I have used this function successfully without the class wrapping.
import Tkinter as tk
import tkFileDialog
import os
class Window(tk.Frame):
def DropdownMenu(options,status,name):
optionFrame = tk.Frame(root)
optionLabel = tk.Label(optionFrame)
optionLabel["text"] = name
optionLabel.pack(side=LEFT)
var = StringVar(root)
var.set(status)
w = tk.OptionMenu(optionFrame, var, *options)
w.pack(side=LEFT)
optionFrame.pack()
return w
def __init__(self,parent):
tk.Frame.__init__(self,parent)
ndim_options = DropdownMenu(("1","2","3"),'-',"Number of dimensions")
if __name__ == "__main__":
root = tk.Tk()
Window(root).pack()
root.mainloop()
When you call DropdownMenu (inside the class), use self ...
ndim_options = self.DropdownMenu((...

why do I get a blank tkinter window?

so when i run this code and click the button:
from Tkinter import *
import thread
class App:
def __init__(self, master):
print master
def creatnew():
admin=Tk()
lab=Label(admin,text='Workes')
lab.pack()
admin.minsize(width=250, height=250)
admin.maxsize(width=250, height=250)
admin.configure(bg='light green')
admin.mainloop()
def other():
la=Label(master,text='other')
la.pack()
bu=Button(master,text='clicks',command=lambda: thread.start_new_thread(creatnew,()))
bu.pack()
other()
Admin = Tk()
Admin.minsize(width=650, height=500)
Admin.maxsize(width=650, height=500)
app = App(Admin)
Admin.mainloop()
i get a second tkinter window but its a white blank screen that makes both programs not respond.
any ideas
Don't use threads. It's confusing the Tkinter mainloop. For a second window create a Toplevel window.
Your code with minimal modifications:
from Tkinter import *
# import thread # not needed
class App:
def __init__(self, master):
print master
def creatnew(): # recommend making this an instance method
admin=Toplevel() # changed Tk to Toplevel
lab=Label(admin,text='Workes')
lab.pack()
admin.minsize(width=250, height=250)
admin.maxsize(width=250, height=250)
admin.configure(bg='light green')
# admin.mainloop() # only call mainloop once for the entire app!
def other(): # you don't need define this as a function
la=Label(master,text='other')
la.pack()
bu=Button(master,text='clicks',command=creatnew) # removed lambda+thread
bu.pack()
other() # won't need this if code is not placed in function
Admin = Tk()
Admin.minsize(width=650, height=500)
Admin.maxsize(width=650, height=500)
app = App(Admin)
Admin.mainloop()

Categories

Resources