Tkinter repeat process, with next button - python

i want to build simple tkinter,
the GUI will display a text and user need to read the text and save the audio. my code currently works but the process not repeatable, my target when user press "NEXT" button the process will repeat the process... and when user press the "END" button process will stop.
is there anywhere how to done it?
import sounddevice as sd
import soundfile as sf
from tkinter import *
def Voice_rec():
fs = 48000
# seconds
duration = 5
myrecording = sd.rec(int(duration * fs),
samplerate=fs, channels=2)
sd.wait()
return sf.write('save_audio.wav', myrecording, fs)
master = Tk()
import os, random
txtfile = random.choice(os.listdir(""))
txtread = "" + txtfile
with open(txtread, "r") as filek:
textfile=filek.read()
# Label(master, text=filek.read()).pack()
wrapper = LabelFrame(master,text="sound record")
wrapper.pack(fill="both",expand="yes",padx=20,pady=20)
lbl3 = Label(wrapper,text=textfile,borderwidth=2, relief="solid",bg = "red")
lbl3.config(font=("Courier", 20))
lbl3.pack()
#def next():
# import os, random
# txtfile = random.choice(os.listdir("path"))
# txtread = "path" + txtfile
# with open(txtread, "r") as filek:
# textfile=filek.read()
# Label(master, text=filek.read()).pack()
# wrapper = LabelFrame(master,text="sound record")
# wrapper.pack(fill="both",padx=20,pady=20)
# lbl3 = Label(wrapper,text=textfile,borderwidth=2, relief="solid",bg = "red")
# lbl3.config(font=("Courier", 20))
# lbl3.pack()
Label(wrapper, text=" Voice Recoder : "
)#.grid(row=0, sticky=W, rowspan=5)
b = Button(wrapper, text="Start", command=Voice_rec)
b.pack()
c = Button(wrapper, text="Next", command=next)
c.pack()
#b.grid(row=0, column=2, columnspan=2, rowspan=2,
# padx=5, pady=5)
mainloop()
above code i refer from this link : https://www.geeksforgeeks.org/build-a-voice-recorder-gui-using-python/

I would suggest you wrap this in a function:
txtfile = random.choice(os.listdir(""))
txtread = "" + txtfile
with open(txtread, "r") as filek:
textfile = filek.read()
which you can then link to your Next button to load a new file each time. Do not re-render the whole UI every time.
In other words, something like this:
master = Tk()
text_file = StringVar()
wrapper = LabelFrame(master, text="sound record")
wrapper.pack(fill="both", expand="yes", padx=20, pady=20)
lbl3 = Label(wrapper)
def next_audio():
path = "path/"
txtfile = random.choice(os.listdir(path))
txtread = os.join(path, txtfile)
with open(txtread, "r") as filek:
text_file.set(filek.read())
print(text_file.get())
lbl3.configure(text=text_file.get())
next_audio()
lbl3.configure(text=text_file.get(), borderwidth=2, relief="solid", bg="red")
lbl3.config(font=("Courier", 20))
lbl3.pack()
Not the best looking code but that was not the intention, just to try and use your code to show what I mean. Also perhaps a tip on Tkinter, rather use the grid geometry manager. pack and place are not best practice with modern Tkinter.
Hope this helped?!

Related

Tkinter button - Replacing old info with new when pressed

Need help solving this problem, I'm a beginner going crazy over this. Each time I press "pingButton1" I want the "pingResult1" to refresh the information insteed of adding new every time I press it. It's a simple "check if ping is good" program.
Any suggestions?
stacking
I've tried using google but nothing is working for me.
from tkinter import *
import os
import subprocess
from time import sleep
menu = Tk()
menu.title("Panel")
menu.geometry("250x380+700+500")
menu.resizable(0, 0)
menu.configure(background="#0d335d")
def close():
screen.destroy()
def pingWindow1():
global ip1
global pingButton1
global screen
screen = Toplevel(menu)
screen.title("Ping Windows")
screen.geometry("300x250+650+300")
screen.configure(background="#0d335d")
blank = Label(screen, bg="#0d335d", text="")
blank.pack()
ip1 = Entry(screen, width=20, bg="white")
ip1.pack()
blank1 = Label(screen, bg="#0d335d", text="")
blank1.pack()
pingButton1 = Button(screen, text="Ping away..", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=pingResult1)
pingButton1.pack()
close_ping = Button(screen, text="Close", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=close)
close_ping.pack()
blank2 = Label(screen, text="", bg="#0d335d")
blank2.pack()
screen.bind('<Escape>', lambda _: close())
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
def overall_mgm():
response = os.system("ping -c 1 sekiiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="KI FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="KI SUCCESS").pack()
def overall_mgm_RO():
response = os.system("ping -c 1 seroiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="RO FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="RO SUCCESS").pack()
# Widget
option = Button(menu, text="Ping IP", width="20", bg="#e5e5e5",height="2", borderwidth=2, relief="ridge", command=pingWindow1)
# Out
option.pack()
menu.mainloop()
I'm guessing I need something like this
if pingButton1 clicked more than once
refresh current Labels( fail & success)
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
with this demo you can change button's text (for example) when pressed.
import tkinter
from functools import partial
# partial is good for passing `function` and `its args`
def button_command(button):
# for example
button.config(text="another value")
# creating new button
# root is whatever you want
button = tkinter.Button(root, text="something")
# add command to button and passing `self`
button.config(command=partial(button_command, button))
button.pack()
adapt this example to your code and you are good to go.

How to cancel or pause a urllib request in python

So I have this program which requests a file from the web and the user can download it. I am using urllib.request and tkinter for my program. The problem is that when the user hits the 'Download' button there is no pause or cancel until the file gets downloaded and the program freezes too. I really want to create a pause or a cancel button, but I do not know how and I want to eliminate the freezing of the program. Should I use another library like 'requests'? Or should I try threading? Can someone guide me through this?
My code(BTW if you know any way to improve my program I would appreciate it a lot if you shared it with me):
from tkinter import *
from tkinter import font as tkFont
import random
import urllib.request
import requests
from tqdm import tqdm
from tqdm.auto import tqdm
def printsth():
print("Yay it works! ")
def main_menu():
root = Tk()
# the top menu
num = IntVar()
# var = IntVar()
menu = Menu(root)
root.config(menu=menu)
submenu = Menu(menu)
menu.add_cascade(label="Settings", menu=submenu)
def custom_op():
custom = Tk()
custom.mainloop()
submenu.add_command(label="Customization ", command=custom_op)
def settings_op():
set_win = Tk()
set_win.mainloop()
submenu.add_command(label="Settings ", command=settings_op)
submenu.add_separator()
submenu.add_command(label="Exit", command=root.destroy)
# the edit menu
editmenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editmenu)
editmenu.add_command(label="Redo...", command=printsth)
# the tool bar
toolbar = Frame(root, bg="light gray")
insert_button = Button(toolbar, text="Insert an image", command=printsth)
insert_button.pack(side=LEFT, padx=2, pady=2)
print_button = Button(toolbar, text="Print", command=printsth)
print_button.pack(side=LEFT, padx=2, pady=2)
toolbar.pack(side=TOP, fill=X)
# the download function
def download_image():
global formatname
if num.get() == 1:
name = random.randrange(1, 100000)
else:
name = str(name_entry.get())
formatname = str(format_entry.get())
'''if var.get() == 1:
operator = str(url_entry.get())
formatname = '.' + operator[-3] + operator[-2] + operator[-1]
else:
pass'''
fullname = str(name) + formatname
url = str(url_entry.get())
fw = open('file-size.txt', 'w')
file_size = int(requests.head(url, headers={'accept-encoding': ''}).headers['Content-Length'])
fw.write(str(file_size))
fw.close()
path = str(output_entry.get()) + "\\"
urllib.request.urlretrieve(url, path.replace("\\", "\\\\") + fullname)
# the status bar
status_bar = Label(root, text="Downloading...", bd=1, relief=SUNKEN, anchor=W)
status_bar.pack(side=BOTTOM, fill=X)
# the download frame
body_frame = Frame(root, bg="light blue")
download_button = Button(body_frame, text="Download! ", command=download_image, border=3, width=20, height=5)
download_design = tkFont.Font(size=12, slant='italic')
download_button['font'] = download_design
download_button.pack(side=LEFT, pady=5, padx=5)
body_frame.pack(side=LEFT, fill=Y)
# the main interaction menu
inter_frame = Frame(root)
url_entry = Entry(inter_frame)
label = Label(inter_frame, text="Enter the image URL: ")
file_format = Label(inter_frame, text="Choose your file format: ")
format_entry = Entry(inter_frame)
file_name = Label(inter_frame, text="File's name: ")
name_entry = Entry(inter_frame)
check_name = Checkbutton(inter_frame, text="Give a random name", variable=num)
# check_format = Checkbutton(inter_frame, text="Download with default format", variable=var)
output_path = Label(inter_frame, text="Choose output path: ")
output_entry = Entry(inter_frame)
file_name.pack(anchor=CENTER, expand=1)
name_entry.pack(anchor=CENTER, expand=1)
check_name.pack(anchor=CENTER, expand=1)
label.pack(anchor=CENTER, expand=1)
url_entry.pack(anchor=CENTER, expand=1)
file_format.pack(anchor=CENTER, expand=1)
format_entry.pack(anchor=CENTER, expand=1)
# check_format.pack(anchor=CENTER)
output_path.pack(anchor=CENTER, expand=1)
output_entry.pack(anchor=CENTER, expand=1)
inter_frame.pack(expand=1)
root.mainloop()
# the end!
main_menu()
You can use reporthook option of urllib.request.urlretrieve() to associate a callback and abort the download by raising exception inside the callback:
downloading = False # flag to indicate whether download is active
def download_progress(count, blksize, filesize):
nonlocal downloading
if downloading:
downloaded = count * blksize
print('downloaded %s / %s' % (downloaded, filesize))
root.update() # let user interact with the GUI
else:
# user selects to abort the download
raise Exception('download aborted!')
# the download function
def download_image():
global formatname
nonlocal downloading
if downloading:
downloading = False
return
download_button.config(text='Stop!') # let user to click the button to abort download
downloading = True
if num.get() == 1:
name = random.randrange(1, 100000)
else:
name = str(name_entry.get())
formatname = str(format_entry.get())
'''if var.get() == 1:
operator = str(url_entry.get())
formatname = '.' + operator[-3] + operator[-2] + operator[-1]
else:
pass'''
fullname = str(name) + formatname
url = str(url_entry.get())
fw = open('file-size.txt', 'w')
file_size = int(requests.head(url, headers={'accept-encoding': ''}).headers['Content-Length'])
fw.write(str(file_size))
fw.close()
path = str(output_entry.get()) + "\\"
try:
urllib.request.urlretrieve(url, path.replace("\\", "\\\\")+fullname, download_progress) # added reporthook callback
except Exception as e:
print(e) # download aborted
else:
print('done')
download_button.config(text='Download!') # resume download button
The text of download_button is changed to Stop! after it is clicked so that user can click it again to abort the download. When the download is aborted/completed, its text is changed back to "Download!".

How to print values in GUI from image in python?

I'm new in GUI developing.Here i'hv created two GUI, one for taking photo and another for showing features.so,i'hv used two functions.but i don't know some things.Now i need two kinds of help from you.
1)what is the command for printing float value in GUI(not on console)?
2)How to calculate the value of mean,variance ,s.d. etc from a image and how to pass those values from one function to another function?
import tkinter as tk
from tkinter.filedialog
import askopenfilename
import shutil
import os
from PIL import Image, ImageTk
window = tk.Tk()
window.title(" ")
window.geometry("500x510")
window.configure(background ="lightgreen")
title = tk.Label(text="Click below to choose picture for testing disease....", background = "lightgreen", fg="Brown", font=("", 15))
title.grid()
def feature():
window.destroy()
window1 = tk.Tk()
window1.title(" ")
window1.geometry("650x510")
window1.configure(background="lightgreen")
def exit():
window1.destroy()
#i want to print some features of image e.g. Mean, variance,s.d. Etc.
button = tk.Button(text="Exit", command=exit)
button.grid(column=0, row=9, padx=20, pady=20)
window1.mainloop()
def openphoto():
import cv2
import numpy as np
dirPath = " "
fileList = os.listdir(dirPath)
for fileName in fileList:
os.remove(dirPath + "/" + fileName)
fileName = askopenfilename(initialdir='', title='Select image for analysis ',
filetypes=[('image files', '.jpg')])
dst = " "
shutil.copy(fileName, dst)
#this is the image
Photo = Image.open(fileName)
render = ImageTk.PhotoImage(photo)
img = tk.Label(image=render, height="250", width="500")
img.image = render
img.place(x=0, y=0)
img.grid(column=0, row=1, padx=10, pady = 10)
title.destroy()
button1.destroy()
button2 = tk.Button(text="Analyse Image", command=feature)
button2.grid(column=0, row=2, padx=10, pady = 10)
button1 = tk.Button(text="Get Photo", command = openphoto)
button1.grid(column=0, row=1, padx=10, pady = 10)
window.mainloop()
Okay, I took some more time to look into it.
Concerning the calculation of the values, your previous question did that correct, however the variables needed to be accessible globally. Concerning the displaying of a text, you have to add a tkinter text widget. If you want to add more calculated values, just google for numpy + 'value your want'.
I've taken your code and created a working example, see the code below. Note that I removed some stuff that wasn't neede for the example, so copy the lines you need to your own code. Also check out this reference for the text widget.
Result:
Code:
Note: I created 2 text widgets deliberately, to show 2 ways of implementing multiple texts
import tkinter as tk
from tkinter.filedialog import askopenfilename
import shutil
import os
from PIL import Image, ImageTk
window = tk.Tk()
window.title(" ")
window.geometry("500x510")
window.configure(background ="lightgreen")
title = tk.Label(text="Click below to choose picture for testing disease....", background = "lightgreen", fg="Brown", font=("", 15))
title.grid()
def feature():
window.destroy()
window1 = tk.Tk()
window1.title(" ")
### create a text widget, place it in window1 and insert the text
width_txt = tk.Text(window1, height=2, width=30, fg="RED", background = "lightgreen", relief="flat")
width_txt.grid(column=0, row=0)
width_txt.insert(tk.END, "Width: " + str(width))
height_txt = tk.Text(window1, height=2, width=30, fg="RED", background = "lightgreen", relief="flat")
height_txt.grid(column=0, row=1)
height_txt.insert(tk.END, "Height: " + str(height) + "\nMean: " + str(mean))
window1.geometry("650x510")
window1.configure(background="lightgreen")
def openphoto():
### this line makes the variables accessible everywhere
global width,height, mean
import numpy as np
fileName = askopenfilename(initialdir='', title='Select image for analysis ',
filetypes=[('image files', '.jpg')])
photo = Image.open(fileName)
#### calculate values
height = np.size(photo, 0)
width = np.size(photo, 1)
mean = np.mean(photo)
render = ImageTk.PhotoImage(photo)
img = tk.Label(image=render, height="250", width="500")
img.image = render
img.place(x=0, y=0)
img.grid(column=0, row=1, padx=10, pady = 10)
title.destroy()
button1.destroy()
button2 = tk.Button(text="Analyse Image", command=feature)
button2.grid(column=0, row=2, padx=10, pady = 10)
button1 = tk.Button(text="Get Photo", command = openphoto)
button1.grid(column=0, row=1, padx=10, pady = 10)
window.mainloop()

Refresh my tkinter label and lets it overwrite it with different output content

I have a Submit button that prints the output on the tkinter widget label. Everytime I change the input and click the Submit the output is displayed but not at the same place i.e. The previous content of the label is not overwritten.
from tkinter import *
from tkinter import filedialog
root = Tk()
root.title("ImageValidation ")
root.geometry("600x600+100+100")
pathlist = [None, None] # holds the two files selected
labels = []
def browse_button(index):
global filename
filename = filedialog.askopenfilename(title = "Choose your file",filetypes = (("jpeg files","*.jpeg"),("all files","*.*")))
pathlist[index] = filename
heading = Label(root, text = "Select 2 images you want to Validate",
font=("arial",15,"bold","underline"), fg="blue").pack()
label1 = Label(root, text = "Enter Image 1", font=("arial",10,"bold"),
fg="black").place(x=10, y = 100)
label2 = Label(root, text = "Enter Image 2", font=("arial",10,"bold"),
fg="black").place(x=10, y = 200)
button = Button(root,text="Choose an Sign1",width = 30,command= lambda:
browse_button(0)).place(x=250, y= 100)
button = Button(root,text="Choose an Sign2",width = 30,command=
lambda: browse_button(1)).place(x=250, y= 200)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1 = Label(root,text=Scriptoutput, width = 200 )
l1.pack(side='bottom', padx=50, pady=50)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)
root.mainloop()
A 'refresh' button that would clear the Label of its content and lets you overwrite it.
I am taking your function ImageVerification() as a blackbox and assuming it is working.
The reason this is happening is because you create a new Label, whenever the Submit button is pressed. What you have to do is to create the display Label outside the function and configure its text, whenever the button is pressed. Something like this.
l1 = Label(root, text="", width=200)
l1.pack(side='bottom', padx=50, pady=50)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1.configure(text=Scriptoutput)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)

Text not being saved in text file on enter-key press using Tkinter

I am building a chat GUI. On enter-key press, I want the text fields to be shown on the text box as well as be saved in a file. I do not want to use separate button. It is being shown in the text box correctly but not getting saved in the file. Please tell me how can it be done. This is my first time using tkinter.
from Tkinter import *
root = Tk()
frame = Frame(root, width=300, height=1000)
frame.pack(side=BOTTOM)
#username entry
L1 = Label(frame, text="User Name")
L1.pack(side = LEFT)
input_username = StringVar()
input_field1 = Entry(frame, text=input_username, width=10)
input_field1.pack(side=LEFT, fill=X)
#addresee entry
L2 = Label(frame, text="#")
L2.pack(side = LEFT)
input_addresee = StringVar()
input_field2 = Entry(frame, text=input_addresee, width=10)
input_field2.pack(side=LEFT, fill=X)
#user comment entry
L3 = Label(frame, text="Comment")
L3.pack(side = LEFT)
input_usertext = StringVar()
input_field3 = Entry(frame, text=input_usertext, width=100)
input_field3.pack(side=LEFT, fill=X)
#write to a file
def save():
text = input_field1.get() + input_field2.get() + input_field3.get()
with open("test.txt", "w") as f:
f.write(text)
#chat box
chats = Text(root)
chats.pack()
def Enter_pressed(event):
input_get_name = input_field1.get()
print(input_get_name)
chats.insert(INSERT, '%s : ' % input_get_name)
input_username.set('')
input_get_add = input_field2.get()
print(input_get_add)
chats.insert(INSERT, '#%s : ' % input_get_add)
input_addresee.set('')
input_get_comment = input_field3.get()
print(input_get_comment)
chats.insert(INSERT, '%s\n' % input_get_comment)
input_usertext.set('')
save()
frame2 = Frame(root)
L2_1 = Label(frame2, text="All chats")
L2_1.pack(side = TOP)
input_field1.bind(Enter_pressed)
input_field2.bind(Enter_pressed)
input_field3.bind("<Return>", Enter_pressed)
frame2.pack()
root.mainloop()
As you said you are setting the input fields to blank
Here's the solution:
def save(text):
with open("test.txt", "w") as f:
f.write(text)
And when calling save:
save(input_get_name+": "+input_get_add+": "+input_get_comment)

Categories