Python Forum

Full Version: bind lambda keypress counter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I am trying to recreate a flash piece in python:
This is a link to a thread that contains the flash based sentry gun program: http://forum.alienslegacy.com/viewtopic.php?f=3&t=3019


I have been playing around with things and so far this is my attempt do program logic for a fire countdown button press counter:
import pygame
from tkinter import *
import tkinter
import keyboard
import pynput


pygame.init()


def final_count(event):
    if count == 0:
      count == 500
    count -= 1
    print(count)
    

# Create object
root = tkinter.Tk()

# Adjust size
root.geometry("640x400")
root.configure(bg='black')
var = StringVar()
var = 500

count = IntVar()
Grid.rowconfigure(root,0,weight=1, uniform='a')
Grid.columnconfigure(root,0,weight=1, uniform='a')
Grid.rowconfigure(root,1,weight=1, uniform='b')
Grid.columnconfigure(root,1,weight=1, uniform='b')

rounds = Button(root,justify=CENTER,textvariable=(var),bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
rounds.grid(row=0,column=0, sticky="EW")
label1 = Label(root, textvariable=count)
label1.grid(row=1, column=0, sticky="EW")
label1.bind('<KeyPress>', lambda f : final_count)



root.mainloop()
I am documenting the progress here:
http://forum.alienslegacy.com/viewtopic.php?f=3&t=19394
And trying to recreate the font used here:
http://forum.alienslegacy.com/viewtopic.php?f=3&t=19399
This is the fire options selection menu that I have not added logic too yet:
# Import module
from tkinter import *
import tkinter
from PIL import Image, ImageTk

import keyboard
import pynput
import pygame

pygame.init()
keys = pygame.key.get_pressed()

# Create object
root = tkinter.Tk()

# Adjust size
root.geometry("640x300")
root.configure(bg='black')

# Specify Grid
# options for grid:
# MINSIZE, PAD, UNIFORM, WEIGHT
# format (windowname,row/column,weight,uniform,pad)
Grid.rowconfigure(root,0,weight=1, uniform='a')
Grid.rowconfigure(root,1,weight=1, uniform='c')
Grid.rowconfigure(root,2,weight=1, uniform='b')
Grid.rowconfigure(root,3,weight=1, uniform='b')
Grid.rowconfigure(root,4,weight=1, uniform='b')
Grid.rowconfigure(root,5,weight=1, uniform='b')
Grid.rowconfigure(root,6,weight=1, uniform='e')
Grid.rowconfigure(root,7,weight=1, uniform='b')
Grid.rowconfigure(root,8,weight=1, uniform='b')
Grid.rowconfigure(root,9,weight=1, uniform='b')
Grid.columnconfigure(root,0,weight=1, uniform='d')
Grid.columnconfigure(root,1,weight=1, uniform='d')
Grid.columnconfigure(root,2,weight=1, uniform='d')
Grid.columnconfigure(root,3,weight=1, uniform='d')
Grid.columnconfigure(root,4,weight=1, uniform='d')
Grid.columnconfigure(root,5,weight=1, uniform='d')
Grid.columnconfigure(root,6,weight=1, uniform='d')
Grid.columnconfigure(root,7,weight=1, uniform='d')
#
#


# notes on different widget options other notes sections will be added for late rreference needs and 
# desired customizations.
# w = Canvas (master, option-value
# bd, bg, cursor, highlight color, width, height
# w = CheckButton(master, option=value)
# Title, activebackground, activeforeground, bg, command, font, image
# w=Entry(master, option=value)
# bd, bg, cursor, command, highlightcolor, width, height
# w=Label(master, option=value)
# bg, bd, command, font, image, width, height
# w = Listbox(master, option=value)
# hightlightcolor, bg, bd, font, image, width, height
# w = MenuButton(master, option=value)
# activebackground, activeforeground, bg, bd, cursor, image, width, height, highlightcolor
# w = Scrollbar(master, option=value)
# width, activebackground, bg, bd, cursor
# w = Text(master, option=value)
# highlightcolor, insertbackground, bg, font, image, width, height
# w = tk.menu button(parent, option, ...)
# activebackground, activeforeground, anchor, background or bg, cursor, compound, direction, disabledforeground, fg, font, height, highlightbackground, highlightcolor, highlightthickness, image, justify, menu, padx, pady, relief, state, takefocus, text, textvariable, underline, width, wraplength
#
#
#

#image files 
#photo = PhotoImage(file = r"c:\Menu_title.png") # old sentry gun menu title

# Specify Framesw = Frame(master, option=value)
# bg, bd, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, width


# Create Buttons
# master, option=value, ...
# activebackground, activeforeground, bd, bg, command, fg, font, height, highlightcolor, image, justify, padx, pady, relief, state, underline, width, wraplength
button_1 = Button(root,justify=CENTER,text="AUTO-REMOTE",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
button_2 = Button(root,justify=CENTER,text="HARD",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
button_3 = Button(root,justify=CENTER,text="SEMIHARD",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
button_4 = Button(root,justify=CENTER,text="SOFT",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
sbutton_1 = Button(root,justify=CENTER,text="BIO",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
sbutton_2 = Button(root,justify=CENTER,text="INERT",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
tsbutton_1 = Button(root,justify=CENTER,text="MULTI SPEC",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
tsbutton_2 = Button(root,justify=CENTER,text="INFRA RED",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
tsbutton_3 = Button(root,justify=CENTER,text="UV",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
wsbutton_1 = Button(root,justify=CENTER,text="SAFE",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
wsbutton_2 = Button(root,justify=CENTER,text="ARMED",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
isbutton_1 = Button(root,justify=CENTER,text="SEARCH",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
isbutton_2 = Button(root,justify=CENTER,text="TEST",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
isbutton_3 = Button(root,justify=CENTER,text="ENGAGED",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
isbutton_4 = Button(root,justify=CENTER,text="INTERROGATE",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
trbutton_1 = Button(root,justify=CENTER,text="AUTO",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
trbutton_2 = Button(root,justify=CENTER,text="SELECTIVE",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
smman = Button(root,justify=CENTER,text="MAN-OVERRIDE",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
smauto = Button(root,justify=CENTER,text="SEMI-AUTO",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
gun_1 = Button(root,borderwidth=7,bg='black',relief=RIDGE,disabledforeground='yellow',state=DISABLED,text="kp")
gun_2 = Button(root,borderwidth=7,bg='black',fg='yellow',disabledforeground='yellow',state=DISABLED,text="kp")
#header = Button(root, image = photo, compound = TOP) # image reference
headernew = Button(root, bg='black',command=root.quit, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER, text="UA 571-C \n REMOTE SENTRY WEAPON SYSTEM")
syst = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="SYSTEM \n   MODE")
weap = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="WEAPON \n   STATUS")
iff = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="IFF \n   STATUS")
test = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="TEST \n   ROUTINE")
target = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="TARGET PROFILE")
spectral = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="SPECTRAL PROFILE")
ts = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="TARGET SELECT")
# bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black'

# Set grid
# widget.grid(grid_options)
# column, columnspan, ipadx, ipady, padx, pady, row, rowspan, sticky
gun_1.grid(row=0,column=0,ipadx=2,ipady=2,padx=2,pady=2,sticky=W)
gun_2.grid(row=0,column=7,ipadx=2,ipady=2,padx=2,pady=2,sticky=E)
headernew.grid(row=0,column=1,columnspan=6,sticky="NSEW")
button_1.grid(row=2,column=0,columnspan=2,sticky="NSEW")
button_2.grid(row=9,column=0,columnspan=3,sticky="NSEW")
button_3.grid(row=8,column=0,columnspan=3,sticky="NSEW")
button_4.grid(row=7,column=0,columnspan=3,sticky="NSEW")
sbutton_1.grid(row=7,column=3,columnspan=2,sticky="NSEW")
sbutton_2.grid(row=8,column=3,columnspan=2,sticky="NSEW")
tsbutton_1.grid(row=7,column=5,columnspan=3,sticky="NSEW")
tsbutton_2.grid(row=8,column=5,columnspan=3,sticky="NSEW")
tsbutton_3.grid(row=9,column=5,columnspan=3,sticky="NSEW")
wsbutton_1.grid(row=2,column=2,columnspan=2,sticky="NSEW")
wsbutton_2.grid(row=3,column=2,columnspan=2,sticky="NSEW")
isbutton_1.grid(row=2,column=4,columnspan=2,sticky="NSEW")
isbutton_2.grid(row=3,column=4,columnspan=2,sticky="NSEW")
isbutton_3.grid(row=4,column=4,columnspan=2,sticky="NSEW")
isbutton_4.grid(row=5,column=4,columnspan=2,sticky="NSEW")
trbutton_1.grid(row=2,column=6,columnspan=2,sticky="NSEW")
trbutton_2.grid(row=3,column=6,columnspan=2,sticky="NSEW")
smman.grid(row=3,column=0,columnspan=2,sticky="NSEW")
smauto.grid(row=4,column=0,columnspan=2,sticky="NSEW")


syst.grid(row=1,column=0,columnspan=2,sticky="NSEW")
weap.grid(row=1,column=2,columnspan=2,sticky="NSEW")
iff.grid(row=1,column=4,columnspan=2,sticky="NSEW")
test.grid(row=1,column=6,columnspan=2,sticky="NSEW")
target.grid(row=6,column=0,columnspan=3,sticky="NSEW")
spectral.grid(row=6,column=3,columnspan=2,sticky="NSEW")
ts.grid(row=6,column=5,columnspan=3,sticky="NSEW")

root.mainloop()
And this is the fire menu that I am trying to figure out how to add keypress count logic too:
# Import module
from tkinter import *
import tkinter
#from PIL import Image, ImageTk
import pygame
import keyboard

pygame.init()

#rounds = ammocounter()
#secsremain = seconds()

# Create object
root = tkinter.Tk()

# Adjust size
root.geometry("640x300")
root.configure(bg='black')

Grid.rowconfigure(root,0,weight=1, uniform='c')
Grid.rowconfigure(root,1,weight=1, uniform='b')
Grid.rowconfigure(root,2,weight=1, uniform='b')
Grid.rowconfigure(root,3,weight=1, uniform='b')
Grid.rowconfigure(root,4,weight=1, uniform='b')
Grid.rowconfigure(root,5,weight=1, uniform='b')
Grid.rowconfigure(root,6,weight=1, uniform='b')
Grid.rowconfigure(root,7,weight=1, uniform='b')
Grid.rowconfigure(root,8,weight=1, uniform='b')
#Grid.rowconfigure(root,9,weight=1, uniform='b')
Grid.columnconfigure(root,0,weight=1, uniform='a')
Grid.columnconfigure(root,1,weight=1, uniform='a')
Grid.columnconfigure(root,2,weight=1, uniform='a')
Grid.columnconfigure(root,3,weight=1, uniform='a')
Grid.columnconfigure(root,4,weight=1, uniform='a')
Grid.columnconfigure(root,5,weight=1, uniform='a')
#Grid.columnconfigure(root,6,weight=1, uniform='a')
#Grid.columnconfigure(root,7,weight=1, uniform='a')

gun_1 = Button(root, borderwidth=7,bg='black',fg='yellow',disabledforeground='yellow',state=DISABLED,text="kp")
gun_2 = Button(root, borderwidth=7,bg='black',fg='yellow',disabledforeground='yellow',state=DISABLED,text="kp")
headernew = Button(root, bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER, text="UA 571-C \n REMOTE SENTRY WEAPON SYSTEM")
rm = Button(root,justify=CENTER,text="R(M)",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
temp = Button(root,justify=CENTER,text="Temp",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
rmbar = Button(root,justify=CENTER,text="R",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
tempbar = Button(root,justify=CENTER,text="T",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
timer = Button(root,justify=CENTER,text="secsremain",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
rounds = Button(root,justify=CENTER,text="rounds",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
crit = Button(root,justify=CENTER,text="CRITICAL",bg='black', fg='yellow', highlightbackground='yellow', highlightcolor='black',activebackground='yellow')
roundsr = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="Rounds \n Remaining")
timestat = Button(root,bg='black',state=DISABLED, fg='yellow',disabledforeground='yellow',highlightbackground='yellow',borderwidth=2,justify=CENTER,text="TIME AT 100% \n (secs)")
quit = Button(root, bg='black', fg='yellow', text='q', command=root.quit)

gun_1.grid(row=0,column=0,rowspan=2,sticky="NS")
gun_2.grid(row=0,column=5,rowspan=2,sticky="NS")
headernew.grid(row=0,column=1,columnspan=4,rowspan=2,sticky="NSEW")
tempbar.grid(row=3,column=4,rowspan=6,sticky="NSEW")
rmbar.grid(row=3,column=5,rowspan=6,sticky="NSEW")
rm.grid(row=2,column=5,sticky="NSEW")
temp.grid(row=2,column=4,sticky="NSEW")
timer.grid(row=7,column=2,columnspan=2,sticky="NS")
rounds.grid(row=3,column=2,columnspan=2,sticky="NS")
timestat.grid(row=7,column=0,columnspan=2,sticky="NSEW")
crit.grid(row=5,column=0,columnspan=2,sticky="NSEW")
roundsr.grid(row=3,column=0,columnspan=2,sticky="NS")
quit.grid(row=8,column=0,sticky="SW")
# Execute tkinter

root.after(200)
root.mainloop()
Line 37 in the first code sample: why do you use a lambda to return the function final_count? Don't you just want the final_count function to be bound to the keypress event? In that case, you should just be passing final_count to bind.
I was playing around trying to teach myself and not all google answers ever work. And your question is very valid and, yes, it would not work.

I did figure out how to get the countdown to work partly the way I want:
#
import pygame
from tkinter import *
import tkinter
import keyboard
import pynput

pygame.init()

# Create object
root = tkinter.Tk()

# Adjust size
root.geometry("640x400")
root.configure(bg='black')
root.title("Sentry Terminal")
var = StringVar()
var = 500

def count(event):
  global counter
  counter.set(counter.get() - 1)

counter = tkinter.IntVar()
counter.set(500)

Grid.rowconfigure(root,0,weight=1, uniform='a')
Grid.columnconfigure(root,0,weight=1, uniform='a')
Grid.rowconfigure(root,1,weight=1, uniform='b')
Grid.columnconfigure(root,1,weight=1, uniform='b')

rounds = Button(root,justify=CENTER,textvariable=var)
rounds.grid(row=0,column=0, sticky="EW")
label1 = Label(root, textvariable=counter)
label1.grid(row=1, column=0, sticky="EW")
root.bind("<KeyPress-f>", count)

while True:
  root.mainloop()
I had to do a root.bind("<KeyPress-f>", count) which bound pressing of the f key to decrement the counter

I go all over the place trying to learn and figure things out.

I found to setup the counter I had to do it this way with a function:
def count(event):
  global counter
  counter.set(counter.get() - 1)

counter = tkinter.IntVar()
counter.set(500)
unfortunately It does not reset at zero which was a limitation of the original flash piece and something I desire to address...

unfortunately with what I am trying to do I am trying to attack each activity part one piece at a time. If my documentation and struggles help someone else, that is fine with me. If I can get help from very helpful folks like you it is greatly appreciated and informative on my struggles with programming, a subject which I struggle with as I am not partial to programming but will do it if I need to create a solution to a problem.

P.S. the python code blocking is not working on this particular post, so sorry on that.
I would add that this walkthrough was the final piece to get the counter part working:
https://learn.sparkfun.com/tutorials/pyt...r-overview

And sparkfun writeups tend to be the best around.
By using classes the attributes can be accessed without using global.
Add logic to the button press event to reset the counter at zero.
import tkinter as tk


INITIAL_COUNTER_VALUE = 500


class TkApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry("640x400")
        self.configure(bg='black')
        self.title("Sentry Terminal")
        self.counter = tk.IntVar()
        self.counter.set(INITIAL_COUNTER_VALUE)
        tk.Grid.rowconfigure(self, 0, weight=1, uniform='a')
        tk.Grid.columnconfigure(self, 0, weight=1, uniform='a')
        tk.Grid.rowconfigure(self, 1, weight=1, uniform='b')
        tk.Grid.columnconfigure(self, 1, weight=1, uniform='b')
        rounds = tk.Button(self, justify=tk.CENTER, textvariable=self.counter)
        rounds.grid(row=0, column=0, sticky="EW")
        label1 = tk.Label(self, textvariable=self.counter)
        label1.grid(row=1, column=0, sticky="EW")
        self.bind("<KeyPress-f>", self.on_keypress_f)

    def on_keypress_f(self, evet):
        counter_value = self.counter.get()
        counter_value = counter_value-1 or INITIAL_COUNTER_VALUE
        self.counter.set(counter_value)


tk_app = TkApp()
tk_app.mainloop()
(Apr-11-2021, 04:35 AM)ndc85430 Wrote: [ -> ]Line 37 in the first code sample: why do you use a lambda to return the function final_count? Don't you just want the final_count function to be bound to the keypress event? In that case, you should just be passing final_count to bind.

(Apr-11-2021, 10:16 AM)Yoriz Wrote: [ -> ]By using classes the attributes can be accessed without using global.
Add logic to the button press event to reset the counter at zero.
import tkinter as tk


INITIAL_COUNTER_VALUE = 500


class TkApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.geometry("640x400")
        self.configure(bg='black')
        self.title("Sentry Terminal")
        self.counter = tk.IntVar()
        self.counter.set(INITIAL_COUNTER_VALUE)
        tk.Grid.rowconfigure(self, 0, weight=1, uniform='a')
        tk.Grid.columnconfigure(self, 0, weight=1, uniform='a')
        tk.Grid.rowconfigure(self, 1, weight=1, uniform='b')
        tk.Grid.columnconfigure(self, 1, weight=1, uniform='b')
        rounds = tk.Button(self, justify=tk.CENTER, textvariable=self.counter)
        rounds.grid(row=0, column=0, sticky="EW")
        label1 = tk.Label(self, textvariable=self.counter)
        label1.grid(row=1, column=0, sticky="EW")
        self.bind("<KeyPress-f>", self.on_keypress_f)

    def on_keypress_f(self, evet):
        counter_value = self.counter.get()
        counter_value = counter_value-1 or INITIAL_COUNTER_VALUE
        self.counter.set(counter_value)


tk_app = TkApp()
tk_app.mainloop()

I am still wrapping my head around things. Is there any documentation you can refer me to to read up on so I might get properly educated?
Yoriz, Thank you, Thank you, Thank you. that redoing of things did the trick on that screen. If you were in town I would buy you a soda out of thanks.

All I know and learn doing this new stuff is how clueless, ignorant, and uneducated I am when it comes to the vast sea of things that are python.

your help is greatly appreciated.
Now I have the fire selection screen I posted above and the fire menu and a loading screen I am trying to tie together.

Do I just create a class for each of these and then initialize each. Though it appears outright the easier option would be to do a
self.destroy()
self.__init__()
this will reload the window identified with defined init of self. just bind those commands to a keypress to preserve the keyboard functionality like in the original.

I could do another class and use say menu as the window identifier then bind spacebar to go to the firemenu so under class TKApp(tk.Tk):
I would add a separate def __init__(select, *args, **kwargs):
declaration and add all the menu options as stated above reformatted to work with it.
Then to move to the fire menu that you kindly rewrote for me just transition to it by binding spacebar to do this:
select.destroy()
self.__init__()
which would close the fire select screen and the open or launch/load the fire menu screen.

Now I want an initial loading screen. I could just do the same and create a def __init__(load, *args, **kwargs): declaration. basically I would just have a static background image and a progress bar which would be very doable with tkinter.

So basically I would have main sections like this under the class:
def __init__(select, *args, **kwargs):
def __init__(load, *args, **kwargs):
def __init__(self, *args, **kwargs):

each one would have their separate declarations and setting and I would use a timer on the initial load screen and then transition to the select screen then use spacebar to transition to the self screen. I would invoke destroy on the current screen and then call init on the screen I want to load.
Sorry but I read your previous post and I don't understand what it is you are trying to do Confused
Pages: 1 2