Updating imagef on TK buttons, each time a button is pressed - python-3.x

I try to build a short of captha app that must run on desktop and emulated on Android, so far I have success with the example "simple calculator" that use TK and Buttons.
I success to load the first row of pictures inside the buttons, but as soon as I try to update the images, buttons disapear
here my code (resumed for two buttons, but same the same)
#!/usr/bin/env python3
# Python program to create a simple GUI
# calculator using Tkinter
from tkinter import *
import os
from PIL import ImageTk,Image, ImageFilter, ImageFont , ImageDraw , ImageOps, ImageFile
# checkea que el script corre en display0, si no, configura el output grafico a este
if os.environ.get('DISPLAY','') == '':
os.environ.__setitem__('DISPLAY', ':0.0')
# globally declare the ThisInstanceImages variable
ThisInstanceImages = []
# Function to update each button is pressed
def press(num):
reloadImages()
def reloadImages():
global ThisInstanceImages
...
aux_IMG = actualImage.crop((10,10,110,110)).resize((250,250))
if len(ThisInstanceImages) == 0:
ThisInstanceImages.append(ImageTk.PhotoImage(aux_IMG))
else:
ThisInstanceImages[0] = ImageTk.PhotoImage(aux_IMG)
aux_IMG = actualImage.crop((110,110,210,210)).resize((250,250))
if len(ThisInstanceImages) == 1:
ThisInstanceImages.append(ImageTk.PhotoImage(aux_IMG))
else:
ThisInstanceImages[1] = ImageTk.PhotoImage(aux_IMG)
# Driver code
if __name__ == "__main__":
# create a GUI window
gui = Tk()
# set the background colour of GUI window
gui.configure(background="light green")
# set the title of GUI window
gui.title("Simple Calculator")
# set the configuration of GUI window
gui.geometry("640x480")
## fisrt run - aux
reloadImages()
# create a Buttons and place at a particular
# location inside the root window .
# when user press the button, the command or
# function affiliated to that button is executed .
button1 = Button(gui, text='', image = ThisInstanceImages[0], fg='black', bg='black',
command=lambda: press(1), height=250, width=250, borderwidth=0)
button1.grid(row=2, column=0)
button2 = Button(gui, text=' 2 ', image = ThisInstanceImages[1], fg='black', bg='black',
command=lambda: press(2), height=250, width=250, borderwidth=0)
button2.grid(row=2, column=1)
...
# start the GUI
gui.mainloop()
the first call [on ## fisrt run - aux] works ok, but as soon as button is pressed, and jump for second time on reloadImages() and hit the seventh line (ThisInstanceImages[0] = ImageTk.PhotoImage(aux_IMG)) app buttons disapear. I try with a little trick to do not delete any image, (really change), same result
here the trick:
def reloadImages():
global ThisInstanceImages
...
aux_IMG = actualImage.crop((10,10,110,110)).resize((250,250))
ThisInstanceImages.append(ImageTk.PhotoImage(aux_IMG))
aux_IMG = actualImage.crop((110,110,210,210)).resize((250,250))
ThisInstanceImages.append(ImageTk.PhotoImage(aux_IMG))
if len(ThisInstanceImages) > 2:
ThisInstanceImages[0] = ThisInstanceImages[2]
is that achivable ??

Related

How to remove a button in a tkinter

The problem is that if I want to remove these buttons, which have been allocated space by x and y, it cannot be and does not generate any error or anything else shows as if it did not do any comedy, and when the button is normal it works as it should
import tkinter as t
root = t.Tk()
def click():
button.pack_forget()
root.maxsize(375, 912)
img = t.PhotoImage(file="background.png")
background = t.Label(root, image=img)
background.pack()
button = t.Button(root, text ="Click\nme", command=click)
button.pack()
button.place(x=157, y=600)
root.mainloop()

how to display a timer in python

hey i am making a program which records desktop screen.
So what i want to do is when ever i click on my start button(tkinter Gui) in my gui window.
It should start a timer like 3.... ,2.... ,1.... in big font directly on my desktop screen and not on my tkinter window. and then my function should start.
How can i do that ..
import tkinter as tk
from tkinter import *
root = Tk()
root.title("our program")
start_cap =tk.button(text='start recording' command=start_capute)
start_cap.pack()
root.mainloop()
Not mentioning the functions and the entire code here as not necessary the code is working fine and i just want to add a new feature of the timer in it.
An minimal example:
import tkinter as tk
# from tkinter import *
def Start():
def Count(Number):
if Number == -1:
win.withdraw()
print("Start") # what you want to do
return False
NumberLabel["text"] = Number
win.after(1000,Count,Number-1)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
win = tk.Toplevel()
win.geometry("+%d+%d"%((screen_width-win.winfo_width())/2,(screen_height-win.winfo_height())/2)) # make it in the center.
win.overrideredirect(1)
win.wm_attributes('-topmost',1) # top window
win.wm_attributes('-transparentcolor',win['bg']) # background transparent.
NumberLabel = tk.Label(win,font=("",40,"bold"),fg='white')
NumberLabel.pack()
win.after(0,lambda :Count(3))
win.mainloop()
root = tk.Tk()
root.title("our program")
start_cap = tk.Button(text='start recording',command=Start)
start_cap.pack()
root.mainloop()

How to stop execution of a function on button click in Python 3?

I'm making a small GUI aplication with tkinter buttons, when button1 is clicked, a function which has infinite loop runs.
I would like to have the possibility to stop the process with another button and reset the aplication to the initial state. I don't know how to do because when the button1 starts the script , button2 is blocked. I want to stop execution of function1 on button2 click. This is my code .
from tkinter import *
root = Tk()
def function1():
x =0
while True : # infinite loop
print(x)
x = x + 1
def function2():
sys.exit()
btn1 = Button(root, text ="Button 1", command = function1)
btn1.place(x=200, y=200)
btn2 = Button(root, text ="Button 2", command = function2)
btn2.place(x= 300,y=300)
root.geometry("400x400")
mainloop()
Thank you.
you can not run the infinite loop in buttons instead you can use recursion. You can call a function recursively and fuction1, function2 can be the functions used to control any variable. Please go thru the following code:
from tkinter import *
running = False
x=0
def scanning():
global x
if running:
x = x+1
print (x)
# After 10 milli second, call scanning again (create a recursive loop)
root.after(10, scanning)
def start():
global running
running = True
def stop():
global running
running = False
root = Tk()
root.title("Continuous Loop")
root.geometry("100x100")
app = Frame(root)
app.grid()
start = Button(app, text="Start counting", command=start)
stop = Button(app, text="Stop counting", command=stop)
start.grid()
stop.grid()
root.after(1000, scanning) # After 1 second, call scanning
root.mainloop()
Hope this will help.

Python 3 Radio button controlling label text

I am in the process of learning Python3 and more of a necessity, the TkInter GUI side. I was working my way through a book by James Kelly, when I encountered this problem. All his examples made a new window with just label/canvas/check box etc which seemed to work OK.
But as I wanted to experiment in a more real world scenario I put most things on one window. This where I encountered my problem. I can not get the radio button in the frame to alter the wording of a label in the parent window.
Complete code is:-
#! /usr/bin/python3
from tkinter import *
def win_pos(WL,WH,xo=0,yo=0) :
# Screen size & position procedure
# Screen size
SW = home.winfo_screenwidth()
SH = home.winfo_screenheight()
# 1/2 screen size
sw=SW/2
sh=SH/2
# 1/2 window size
wl=WL/2
wh=WH/2
# Window position
WPx=sw-wl+xo
WPy=sh-wh+yo
# Resulting string
screen_geometry=str(WL) + "x" + str(WH) + "+" + str(int(WPx)) + "+" \ + str(int(WPy))
return screen_geometry
# Create a window
home=Tk()
home.title("Radio buttons test")
# Set the main window
home.geometry(win_pos(600,150))
lab1=Label(home)
lab1.grid(row=1,column=1)
fraym1=LabelFrame(home, bd=5, bg="red",relief=SUNKEN, text="Label frame text")
fraym1.grid(row=2,column=2)
laybl1=Label(fraym1, text="This is laybl1")
laybl1.grid(row=0, column=3)
var1=IntVar()
R1=Radiobutton(fraym1, text="Apple", variable=var1, value=1)
R1.grid(row=1, column=1)
R2=Radiobutton(fraym1, text="Asus", variable=var1, value=2)
R2.grid(row=1, column=2)
R3=Radiobutton(fraym1, text="HP", variable=var1, value=3)
R3.grid(row=1, column=3)
R4=Radiobutton(fraym1, text="Lenovo", variable=var1, value=4)
R4.grid(row=1, column=4)
R5=Radiobutton(fraym1, text="Toshiba", variable=var1, value=5)
R5.grid(row=1, column=5)
# Create function used later
def sel(var) :
selection="Manufacturer: "
if var.get() > 0 :
selection=selection + str(var.get())
lab1.config(text=selection)
R1.config(command=sel(var1))
R2.config(command=sel(var1))
R3.config(command=sel(var1))
R4.config(command=sel(var1))
R5.config(command=sel(var1))
R1.select()
mainloop()
I realise that there is room for improvement using classes/functions but I need to get this resolved in my head before I move on. As it can be hopefully seen, I'm not a complete novice to programming, but this is doing my head in.
Can a solution, and reasoning behind the solution, be given?
You can modify your label's text by assigning the same variable class object, var1 as its textvariable option as well but since lab1's text is slightly different, try removing:
R1.config(command=sel(var1))
R2.config(command=sel(var1))
R3.config(command=sel(var1))
R4.config(command=sel(var1))
R5.config(command=sel(var1))
R1.select()
and modify sel to:
def sel(*args) :
selection="Manufacturer: "
selection=selection + str(var1.get())
lab1.config(text=selection)
and then call var1.trace("w", sel) somewhere before mainloop as in:
...
var1.trace("w", sel)
mainloop()
Also for a simple example:
import tkinter as tk
root = tk.Tk()
manufacturers = ["man1", "man2", "man3", "man4", "man5"]
lbl = tk.Label(root, text="Please select a manufacturer.")
lbl.pack()
# create an empty dictionary to fill with Radiobutton widgets
man_select = dict()
# create a variable class to be manipulated by radiobuttons
man_var = tk.StringVar(value="type_default_value_here_if_wanted")
# fill radiobutton dictionary with keys from manufacturers list with Radiobutton
# values assigned to corresponding manufacturer name
for man in manufacturers:
man_select[man] = tk.Radiobutton(root, text=man, variable=man_var, value=man)
#display
man_select[man].pack()
def lbl_update(*args):
selection="Manufacturer: "
selection=selection + man_var.get()
lbl['text'] = selection
#run lbl_update function every time man_var's value changes
man_var.trace('w', lbl_update)
root.mainloop()
Example with label's identical to that of radiobutton's value:
import tkinter as tk
root = tk.Tk()
# radiobutton group will the button selected with the value=1
num = tk.IntVar(value=1)
lbl = tk.Label(root, textvariable=num)
zero = tk.Radiobutton(root, text="Zero", variable=num, value=0)
one = tk.Radiobutton(root, text="One", variable=num, value=1)
#display
lbl.pack()
zero.pack()
one.pack()
root.mainloop()

How do I make a button console using Tkinter?

I have got a script wiht nine diferent options in a text menu. I would like to change the menu for a GUI using tkinter.
The menu has nine options which are a bucle if, elif... esle from 1 to 9. The last one is the 'exit' one.
How do I transform the menu if, elif, elif....else in a window with nine buttons each one for a different option and run the same script ?
I am trying the following code:
from tkinter import*
ventana = Tk()
variable = ''
def opcion1():
global variable
variable = '1'def opcion2 ():
global variable
variable = '2'
root = Tk()
boton1 = Button(ventana, text='OPCION1',command=opcion1)
boton1.pack()
boton2 = Button(ventana, text='OPCION2',command=opcion2)
boton2.pack()
botonSalir = Button(ventana, text='EXIT',command=quit)
botonSalir.pack()
root.mainloop()
How can I do that?
Hopefully this helps!
from Tkinter import *
root = Tk()
def f1():
print('f1')
def f2():
print('f2')
def f3():
print('f3')
MODES = [("Option1", f1, '1'), ("Option2", f2, '2'), ("Option3", f3, '3')]
v = StringVar()
v.set("L") # initialize
for text, function, mode in MODES:
b = Radiobutton(root, text=text, indicatoron=0, variable=v, command=function, value=mode)
b.pack(anchor=W)
root.mainloop()

Resources