how to break looping in tkinter? - python-3.x

this is my code.
from PyPDF2 import PdfFileReader
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
root = tk.Tk()
label_list = []
def get_info(path):
with open(path, 'rb') as f:
pdf = PdfFileReader(f)
info = pdf.getDocumentInfo()
page = pdf.getPage(4)
label_list[0].config(text = "Title")
label_list[1].config(text = info.title)
label_list[2].config(text = "Author")
label_list[3].config(text = info.author)
label_list[4].config(text = "Subject")
label_list[5].config(text = info.subject)
label_list[6].config(text = "Abstract")
label_list[7].config(text = page.extractText())
save = tk.Button(root, text="Save")
save.pack()
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
get_info(filename)
browsebutton = tk.Button(root, text="Choose a File", command=browsefunc)
browsebutton.pack()
pathlabel = tk.Label(root)
pathlabel.pack()
for i in range(8):
label_list.append(tk.Label(root, text=""))
label_list[i].pack()
root.mainloop()
i added button save which the button will show when i choose the file, and when i choose a new file, i got 2 save buttons and more.
how can i break the data, and when i choose a new file i only have 1 button?

Here is one way you can get the button to show when you need it and then get rid of it when you don't.
We can have a tracking variable to see if we currently have a button open and when we use the button we can get rid of the button as part of the function. So create when we need it and destroy when its done.
from PyPDF2 import PdfFileReader
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
root = tk.Tk()
label_list = []
track_save_button = False
def save_func():
global track_save_button, save
# your code for saving data here
save.destroy()
track_save_button = False
def get_info(path):
global track_save_button, save
if track_save_button == False:
save = tk.Button(root, text="Save", command=save_func)
save.pack()
track_save_button = True
with open(path, 'rb') as f:
pdf = PdfFileReader(f)
info = pdf.getDocumentInfo()
page = pdf.getPage(4)
label_list[0].config(text = "Title")
label_list[1].config(text = info.title)
label_list[2].config(text = "Author")
label_list[3].config(text = info.author)
label_list[4].config(text = "Subject")
label_list[5].config(text = info.subject)
label_list[6].config(text = "Abstract")
label_list[7].config(text = page.extractText())
else:
print("Save Button is already active!")
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
get_info(filename)
browsebutton = tk.Button(root, text="Choose a File", command=browsefunc)
browsebutton.pack()
pathlabel = tk.Label(root)
pathlabel.pack()
for i in range(8):
label_list.append(tk.Label(root, text=""))
label_list[i].pack()
root.mainloop()

Related

How can I get the data (DoubleVar) from multiple Tkinter Entry boxes and save them to a .dat file and retrieve them later to repopulate said boxes

First let me say brand new here and brand new to codeing
The whole idea I'm trying to get done is have a list of Parameters that can be saved by the user and used later with out having to change the code
I have a bigger program I am working on, but I have simplified this code to figure this out. I have the following code that will get and receive a single Entry box, if I try to add a second entry box to the "save" then it just adds to to the first Entry box like concatenation.
import tkinter
from tkinter import *
from tkinter import filedialog
from tkinter import ttk
import sqlite3
import pickle
#---------------------------------------------------------------
#---------------------------------------------------------------
root = Tk()
root.title("Cabinet Cut List Calculator")
frame = LabelFrame(root)
frame.pack()
#---------------------------------------------------------------
#---------------------------------------------------------------
toek = DoubleVar(value=3.5)
default_hgt = IntVar(value=42)
parms_list = [toek, default_hgt]
#---------------------------------------------------------------
#---------------------------------------------------------------
def SaveParms():
parms_name = filedialog.asksaveasfilename(initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Save Parameters", filetypes=(("Dat Files", "*.dat"),("All Files", "*.*")))
if parms_name:
if parms_name.endswith(".dat"):
pass
else:
parms_name = f"{parms_name}.dat"
parms_list = y.get()
output_parms = open(parms_name, 'wb')
pickle.dump(parms_list, output_parms)
def LoadParms():
parms_name = filedialog.askopenfilename(initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Load Parameters", filetypes=(("Dat Files", "*.dat"),("All Files", "*.*")))
if parms_name:
y.delete(0, END)
input_parm = open(parms_name, "rb")
load_item = pickle.load(input_parm)
for i in load_item:
y.insert(END, i)
def DelParms():
y.delete(0,END)
#---------------------------------------------------------------
#---------------------------------------------------------------
the_menu = Menu(root)
root.config(menu = the_menu)
#^^^^^^^^^^
file_menu = Menu(the_menu, tearoff=False)
the_menu.add_cascade(label="File", menu= file_menu)
#^^^^^^^^^^
file_menu.add_command(label="Save Parameters", command= SaveParms)
file_menu.add_command(label="Load Parameters", command= LoadParms)
file_menu.add_separator()
file_menu.add_command(label="Clear Parameters", command= DelParms)
#---------------------------------------------------------------
#---------------------------------------------------------------
y = Entry(frame, textvariable=toek)
y.pack(side=RIGHT)
yl= Label(frame, text = "1....")
yl.pack()
frame2 = LabelFrame(root)
frame2.pack()
x = Entry(frame2, textvariable= default_hgt)
x.pack(side=RIGHT)
xl= Label(frame2, text = "2....")
xl.pack()
#---------------------------------------------------------------
root.mainloop()
I know this is going to involve some sort of for loop but I cant figure it out. if I try
for i in parms_list:
parms_list =+ i.get()
in the Save function I get
parms_list =+ i.get()
^^^^^
AttributeError: 'str' object has no attribute 'get'
PICKLE is beyond my limited scope of knowledge.
I know there is a simple solution here, I have tried other things but I am at a loss.
Thanks have a great day
EDIT:
I have been working on this for a couple of days and this is what I have come up with for the "save" function
if parms_name:
if parms_name.endswith(".dat"):
pass
else:
parms_name = f"{parms_name}.dat"
new_list = []
for i in entry_list:
entry_name = [key for key, value in globals().items() if value == i]
new_list += [(entry_name[0] + ".get()")]
# print(new_list)
# new_list = [y.get(), x.get()]
output_parms = open(parms_name, 'wb')
pickle.dump(new_list, output_parms)
so I am getting closer but the "new_list" is just strings and i need it to run the .get() function on the variable, I'll keep working at it but if there is any help out there I would appreciate it, thanks.
So as most things in life there is more than one way to do things. I was using .dat files because that was what I was working with a tutorial. After banging my head against a wall and doing research in between I ended up using .ini (config file) and here is my working code.
#---------------------------------------------------------------
import tkinter
from tkinter import *
from tkinter import filedialog
from tkinter import ttk
import sqlite3
from configparser import ConfigParser
import os
#---------------------------------------------------------------
#---------------------------------------------------------------
root = Tk()
root.title("Cabinet Cut List Calculator")
frame = LabelFrame(root)
frame.pack()
#---------------------------------------------------------------
#---------------------------------------------------------------
toek = DoubleVar(value=3.5)
default_hgt = IntVar(value=42)
#---------------------------------------------------------------
#---------------------------------------------------------------
def SaveParms():
save_name = filedialog.asksaveasfilename(initialdir="/Users/Owner/Desktop/Python/cab databases/Parameters", title="Save Parameters", filetypes=(("ini Files", "*.ini"),("All Files", "*.*")))
if save_name:
if save_name.endswith(".ini"):
pass
else:
save_name = f"{save_name}.ini"
parser = ConfigParser()
def write_file():
if save_name:
parser.write(open(save_name, 'w'))
if not os.path.exists(save_name):
parser['parameters'] = {'var1': y.get(), 'var2': x.get()}
write_file()
def LoadParms():
load_name = filedialog.askopenfilename(initialdir="/Users/Owner/Desktop/Python//cab databases/Parameters", title="Load Parameters", filetypes=(("ini Files", "*.ini"),("All Files", "*.*")))
if load_name:
parser = ConfigParser()
parser.read(load_name)
saved_toek = parser.get('parameters', 'var1')
saved_default_hgt = parser.get('parameters', 'var2')
saved_toek = DoubleVar(value = saved_toek)
saved_default_hgt = IntVar(value = saved_default_hgt)
y.configure(textvariable=saved_toek)
x.configure(textvariable=saved_default_hgt)
def DelParms():
y.delete(0,END)
x.delete(0,END)
#---------------------------------------------------------------
#---------------------------------------------------------------
the_menu = Menu(root)
root.config(menu = the_menu)
#^^^^^^^^^^
file_menu = Menu(the_menu, tearoff=False)
the_menu.add_cascade(label="File", menu= file_menu)
#^^^^^^^^^^
file_menu.add_command(label="Save Parameters", command= SaveParms)
file_menu.add_command(label="Load Parameters", command= LoadParms)
file_menu.add_separator()
file_menu.add_command(label="Clear Parameters", command= DelParms)
#---------------------------------------------------------------
#---------------------------------------------------------------
y = Entry(frame, textvariable=toek)
y.pack(side=RIGHT)
yl= Label(frame, text = "1....")
yl.pack()
frame2 = LabelFrame(root)
frame2.pack()
x = Entry(frame2, textvariable= default_hgt)
x.pack(side=RIGHT)
xl= Label(frame2, text = "2....")
xl.pack()
#---------------------------------------------------------------
root.mainloop()

how to accept filename from user and save the sound file in python

i am trying to record sound from pyaudio in python and making a gui for the same.
my code run fine when i use datetime library and give the filename eg.sound_2020_21_04_03_40.wav which is current date,time but when i try to take the filename from user with tkinter (from tkinter.filedialog import asksaveasfile) it is saving the sound file but its empty with 0 bytes.
can any on e help me in this. this is my coding part of stop button which terminate the code and save the file.
import tkinter as tk
import threading
import pyaudio
import wave
from tkinter import *
import tkinter.font as font
from tkinter.filedialog import asksaveasfile
class App():
chunk = 1024
sample_format = pyaudio.paInt16
channels = 2
fs = 44100
frames = []
def __init__(self, master):
self.isrecording = False
myFont = font.Font(weight="bold")
self.button1 = tk.Button(main, text='Record',command=self.startrecording,height=2,width=20,bg='#0052cc', fg='#ffffff')
self.button2 = tk.Button(main, text='stop',command=self.stoprecording,height=2,width=20,bg='#0052cc', fg='#ffffff')
self.button1['font'] = myFont
self.button2['font'] = myFont
self.button1.place(x=30, y=30)
self.button2.place(x=280, y=30)
def startrecording(self):
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.sample_format,channels=self.channels,rate=self.fs,frames_per_buffer=self.chunk,input=True)
self.isrecording = True
print('Recording')
t = threading.Thread(target=self.record)
t.start()
def stoprecording(self):
self.isrecording = False
print('recording complete')
self.filename = asksaveasfile(initialdir = "/",title = "Save as",mode='w',filetypes = (("audio file","*.wav"),("all files","*.*")),defaultextension=".wav")
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.sample_format))
wf.setframerate(self.fs)
wf.writeframes(b''.join(self.frames))
wf.close()
main.destroy()
def record(self):
while self.isrecording:
data = self.stream.read(self.chunk)
self.frames.append(data)
main = tk.Tk()
main.title('recorder')
main.geometry('520x120')
app = App(main)
main.mainloop()
image is here
It's strange that no exceptions were risen, because when you call askopenfile(...) it returns a file object (and opens an empty file for reading - that file you have seen), but wave.open(...) expects a filename. To get it, you need to use askopenfilename(...) instead of askopenfile(...). And don't forget to import askopenfilename in the top of your code.
Here is the full code (I have refactored it according to PEP8):
import tkinter as tk
import threading
import pyaudio
import wave
from tkinter import *
import tkinter.font as font
from tkinter.filedialog import asksaveasfilename
class App():
chunk = 1024
sample_format = pyaudio.paInt16
channels = 2
fs = 44100
frames = []
def __init__(self, master):
self.isrecording = False
myFont = font.Font(weight="bold")
self.button1 = tk.Button(main, text='Record', command=self.startrecording,
height=2, width=20, bg='#0052cc', fg='#ffffff')
self.button2 = tk.Button(main, text='stop', command=self.stoprecording,
height=2, width=20, bg='#0052cc', fg='#ffffff')
self.button1['font'] = myFont
self.button2['font'] = myFont
self.button1.place(x=30, y=30)
self.button2.place(x=280, y=30)
def startrecording(self):
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.sample_format, channels=self.channels,
rate=self.fs, frames_per_buffer=self.chunk, input=True)
self.isrecording = True
print('Recording')
t = threading.Thread(target=self.record)
t.start()
def stoprecording(self):
self.isrecording = False
print('recording complete')
self.filename = asksaveasfilename(initialdir="/", title="Save as",
filetypes=(("audio file", "*.wav"), ("all files", "*.*")),
defaultextension=".wav")
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.sample_format))
wf.setframerate(self.fs)
wf.writeframes(b''.join(self.frames))
wf.close()
main.destroy()
def record(self):
while self.isrecording:
data = self.stream.read(self.chunk)
self.frames.append(data)
print("does it")
main = tk.Tk()
main.title('recorder')
main.geometry('520x120')
app = App(main)
main.mainloop()

How can i get data from file path using tkinter and PdFileReader

I use this method :
from PyPDF2 import PdfFileReader
from tkinter import *
from tkinter import filedialog
import os
root = Tk()
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
browsebutton = Button(root, text="Browse", command=browsefunc)
browsebutton.pack()
pathlabel = Label(root)
pathlabel.pack()
def get_info(path):
with open(path, 'rb') as f:
pdf = PdfFileReader(f)
info = pdf.getDocumentInfo()
number_of_pages = pdf.getNumPages()
print(info)
author = info.author
creator = info.creator
producer = info.producer
subject = info.subject
title = info.title
if __name__ == '__main__':
path = pathlabel.pack()
get_info(path)
mainloop()
However, i get the following error:
TypeError: invalid file: None
How can i get the file from pathlabel?
Is it possible to open the file from file path?
I see a couple problems here.
Delete this:
if __name__ == '__main__':
path = pathlabel.pack()
get_info(path)
what this is doing is making path = to the result of pathlabel.pack(). That result will always be None as pack() is always going to return None. Then you are passing None to the get_info() function.
Instead lets call get_info from your brousefunc() functions.
Change brousefunc() to this:
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
get_info(filename)
This will update your label and then also send the correct file path to the get_info function.
If you still wish to use the label's text for the file path you can do path = pathlabel["text"] as this will assign the value of the text to the path.
I can't test PyPDF2 on my end but the below should work for you.
from PyPDF2 import PdfFileReader
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
def get_info(path):
with open(path, 'rb') as f:
pdf = PdfFileReader(f)
info = pdf.getDocumentInfo()
number_of_pages = pdf.getNumPages()
author = info.author
creator = info.creator
producer = info.producer
subject = info.subject
title = info.title
print(number_of_pages, author, creator, producer, subject, title)
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
get_info(filename)
browsebutton = tk.Button(root, text="Browse", command=browsefunc)
browsebutton.pack()
pathlabel = tk.Label(root)
pathlabel.pack()
root.mainloop()
To address your question in the comments here is an example that displays in the GUI.
from PyPDF2 import PdfFileReader
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
label_list = []
def get_info(path):
with open(path, 'rb') as f:
pdf = PdfFileReader(f)
info = pdf.getDocumentInfo()
label_list[0].config(text=pdf.getNumPages())
label_list[1].config(text=info.author)
label_list[2].config(text=info.creator)
label_list[3].config(text=info.producer)
label_list[4].config(text=info.subject)
label_list[5].config(text=info.title)
def browsefunc():
filename = filedialog.askopenfilename()
pathlabel.config(text=filename)
get_info(filename)
browsebutton = tk.Button(root, text="Browse", command=browsefunc)
browsebutton.pack()
pathlabel = tk.Label(root)
pathlabel.pack()
for i in range(6):
label_list.append(tk.Label(root, text=""))
label_list[i].pack()
root.mainloop()

Using Tkinter and suprocess.call

I would like to use tkinter to open a window that will allow a user to select two separate files that will be manipulated several times within my script. I am having trouble finding a way to set the file that will be selected using the button in my tkinter window as a variable so that it can be used within subprocess.call. I have found invoke() but it doesn't seem to have any affect. Any ideas on what I might do would be greatly appreciated.
import os
import sys
import gdal
from gdalconst import *
import numpy as np
import math
import subprocess
from subprocess import call
import math
import datetime
import shutil
import tkinter
from tkinter import *
from tkinter import filedialog
newpath = os.path.expanduser('~\\Desktop\\Components\\Float32')
if not os.path.exists(newpath):
os.makedirs(newpath)
newpath_2 = os.path.expanduser('~\\Desktop\\Components\\Zeros')
if not os.path.exists(newpath_2):
os.makedirs(newpath_2)
newpath_3 = os.path.expanduser('~\\Desktop\\Components\\db_Files')
if not os.path.exists(newpath_3):
os.makedirs(newpath_3)
if __name__== '__main__':
# Set all of the necessary constants so that the script can create and save the pertinent files
# on the users desktop
#tk1 = Tk()
#tk2 = Tk()
#callTK = 'src_dataset =' + tk1
#callTK_2 = 'srcVH =' + tk2
gdalTranslate = 'C:\Program Files (x86)\GDAL\gdal_translate.exe'
tk1.fileName = filedialog.askopenfilename(text="Open HV File")
tk2.fileName = filedialog.askopenfilename(text="Open VH File")
dst_dataset = os.path.expanduser('~\\Desktop\\Components\\Float32\\newHV32.img')
dstVH = os.path.expanduser('~\\Desktop\\Components\\Float32\\newVH32.img')
sttime = datetime.datetime.now().strftime('(Time_Run = %Y-%d-%m_%H:%M:%S)')
wheel_install_1 = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\wheel_install.py')
wheel_install_2 = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\wheel_install2.py')
ridofz = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\ridofZsv2.py')
to_dB = os.path.expanduser('~\\Desktop\\Components\\Sigma_Test\\to_dBv2.py')
db_HV = os.path.expanduser('~\\Desktop\\Components\\dB_Files\\newHVdB.img')
db_VH = os.path.expanduser('~\\Desktop\\Components\\dB_Files\\newVHdB.img')
cmd = "-ot float32 -of HFA" # hopefully this works
# Install necessary packages, which are GDAL and Numpy
# try:
#os.system(wheel_install_1)
#print ("GDAL intalled")
#os.system(wheel_install_2)
#print ("Numpy installed")
#except:
#print ("The packages are't installing properly")
#sys.exit()
# Create three new folders which will house the files that will be created
# along each sequential step of the script
#newpath = os.path.expanduser('~\\Desktop\\Components\\Float32')
#if not os.path.exists(newpath):
#os.makedirs(newpath)
#newpath_2 = os.path.expanduser('~\\Desktop\\Components\\Zeros')
#if not os.path.exists(newpath_2):
#os.makedirs(newpath_2)
#newpath_3 = os.path.expanduser('~\\Desktop\\Components\\db_Files')
#if not os.path.exists(newpath_3):
#os.makedirs(newpath_3)
root = Tk()
#root.fileName = filedialog.askopenfilename()
root.title("Utilis Sigma Test")
root.iconbitmap(r"C:\Users\jack.UTILIS\Desktop\images\sigma.ico")
root.configure(background="#179EBB")
topFrame = Frame(root)
topFrame.pack()
photo = PhotoImage(file="C:\\Users\\jack.UTILIS\\Desktop\\images\\Utilis_Branding2015_FINAL_Small.gif")
label = Label(root, image=photo)
label.pack(side=RIGHT)
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
button1 = Button(root, text="Open HV File", fg="black", command=filedialog.askopenfilename)
button2 = Button(root, text="Open VH FIle", fg="black", command=filedialog.askopenfilename)
button1.pack(side=LEFT)
button2.pack(side=RIGHT)
hvfullCmd = ' '.join([gdalTranslate, cmd, tk1.fileName,dst_dataset])
subprocess.call(hvfullCmd)
vhfullCmd = ' '.join([gdalTranslate,cmd, tk2.fileName,dstVH])
subprocess.call(vhfullCmd)
root.mainloop()
You have to create own function which get filename from askopenfilename and does something with this file. Then you can assign this file to button using command=
import tkinter as tk
from tkinter import filedialog
# --- functions ---
def on_click():
filename = filedialog.askopenfilename()
if filename:
print("Filename:", filename)
else:
print("Filename: not selected")
# --- main ---
root = tk.Tk()
btn = tk.Button(root, text='Click Me', command=on_click)
btn.pack()
root.mainloop()

tkinter python entry not being displayed

I have created a Form with labels and entries..but for some reason the entries are not being created,
peoplegui.py
from tkinter import *
from tkinter.messagebox import showerror
import shelve
shelvename = 'class-shelve'
fieldnames = ('name','age','job','pay')
def makewidgets():
global entries
window = Tk()
window.title('People Shelve')
form = Frame(window)
form.pack()
entries = {}
for (ix, label) in enumerate(('key',) + fieldnames):
lab = Label(form, text=label)
ent = Entry(form)
lab.grid(row=ix, column=0)
lab.grid(row=ix, column=1)
entries[label] = ent
Button(window, text="Fetch", command=fetchRecord).pack(side=LEFT)
Button(window, text="Update", command=updateRecord).pack(side=LEFT)
Button(window, text="Quit", command=window.quit).pack(side=RIGHT)
return window
def fetchRecord():
print('In fetch')
def updateRecord():
print('In update')
if __name__ == '__main__':
window = makewidgets()
window.mainloop()
When I run it the labels are created but not the entries.
You have forgetten to grid the entries.

Resources