How to cancel or pause a urllib request in python - 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!".

Related

adding date to tkinter data entry

I'm trying to make a gui of a small project. I want to add the ability to once hitting add_item to add a data entry, it adds a time stamp to it as well. I'm very new to tkinter so any help would be great. I tried something like this:
tk.Button(root, text='add_item', command=lambda :text.insert("end", time.strftime("%d/%m/%Y%H:%M:%S")+'\n'))
b2.pack(side=tkinter.LEFT)
but couldn't get it to work with the rest of the code. I'm assuming it needs a lambda function, not sure how to set it up though.
import tkinter as tk
from datetime import datetime
import time
#1
now = datetime.now()
print ("Current date and time : ")
print (now.strftime("employee-attendance-list-%Y-%m-%d.csv"))
filename = datetime.now().strftime('employee-attendance-list-%Y-%m-%d.csv')
def dt_ins():
e.insert(0, time.asctime())
root = tk.Tk()
root.title("List App")
root.geometry("400x400")
def handler(e):
label= Label(win, text= "You Pressed Enter")
label.pack()
def retrievedata():
''' get data stored '''
global list_data
list_data = []
try:
with open (filename, "r", encoding="utf-8") as file:
for f in file:
listbox.insert(tk.END, f.strip())
list_data.append(f.strip())
print(list_data)
except:
pass
def reload_data():
listbox.delete(0, tk.END)
for d in list_data:
listbox.insert(0, d)
def add_item(event=1):
global list_data
if content.get() != "":
listbox.insert(tk.END, content.get())
list_data.append(content.get())
content.set("")
def delete():
global list_data
listbox.delete(0, tk.END)
list_data = []
def delete_selected():
try:
selected = listbox.get(listbox.curselection())
listbox.delete(listbox.curselection())
list_data.pop(list_data.index(selected))
# reload_data()
# # listbox.selection_clear(0, END)
listbox.selection_set(0)
listbox.activate(0)
listbox.event_generate("<<ListboxSelect>>")
print(listbox.curselection())
except:
pass
def quit():
global root
with open (filename, "w", encoding="utf-8") as file:
for d in list_data:
file.write(d + "\n")
root.destroy()
# LISTBOX
content = tk.StringVar()
entry = tk.Entry(root, textvariable=content)
entry.pack()
button = tk.Button(root, text="Add Item", command=lambda: [add_item(), dt_ins()])
button.pack()
entry.bind("<Return>", add_item)
button_delete = tk.Button(text="Delete", command=delete)
button_delete.pack()
button_delete_selected = tk.Button(text="Delete Selected", command=delete_selected)
button_delete_selected.pack()
listbox = tk.Listbox(root)
listbox.pack()
entry.bind("<Return>,", add_item)
bquit = tk.Button(root, text="Quit and save", command=quit)
bquit.pack()
retrievedata()
root.mainloop()

Tkinter repeat process, with next button

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?!

Pause function in pygame mixer is not working

I am currently making a GUI with Tkinter that plays music. The program is able to correctly play the songs, and I am trying to implement a pause button. This is the code I have, does anyone know why this might not be working? I know the button is linked properly since I have tried printing something out when the button is clicked, and that works. Also, there are no error messages, the audio is just not pausing.
import pygame
from tkinter import *
import os
import urllib.request
import urllib.parse
import re
import requests
from PIL import ImageTk, Image
class Application(Frame):
def __init__(self, master):
super().__init__(master)
self.grid()
pygame.mixer.init()
self.downloadNum = 1
self.pack(fill = BOTH, expand = 1)
self.songDict = {}
num = 1
while True:
if os.path.exists(str(num)+'.jpg'):
os.remove(str(num)+'.jpg')
num += 1
else:
break
self.create_widgets()
def create_widgets(self):
Label(self, text="Available Songs").grid(row=0, column=0)
for filename in os.listdir(r'C:\Users\alvin\Documents\School'):
if filename.endswith(".mp3"):
string = ""
for x in filename:
if x == "_":
string += " "
else:
if x == ".":
break
string += x
Label(self, text=string).grid()
Label(self, text = "Enter your song!").grid(row=0, column = 1)
self.entryBox = Entry(self)
self.entryBox.grid(row=1, column =1)
Button(self, text="Play!", command = self.playSong).grid(row=2, column =1)
Label(self).grid(row=3, column =1)
Label(self, text="Currently Playing:").grid(row=4, column=1)
self.playing = Label(self, text="")
self.playing.grid(row=5, column=1)
def playSong(self):
self.song = self.entryBox.get()
self.newsong = ""
for x in self.song:
if x == " ":
self.newsong += "_"
else:
self.newsong += x
self.newsong = self.newsong.title()
self.newsong = self.newsong + ".mp3"
pygame.mixer.music.load(self.newsong)
pygame.mixer.music.play(0)
self.playing.configure(text=self.song.title())
query_string = urllib.parse.urlencode({"search_query": self.song.title()})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
f = open(str(self.downloadNum) +'.jpg','wb')
f.write(requests.get('https://img.youtube.com/vi/' + search_results[0] + '/default.jpg').content)
f.close()
self.songDict[self.downloadNum] = self.newsong
load = Image.open(str(self.downloadNum) + ".jpg")
render = ImageTk.PhotoImage(load)
img = Label(self, image=render)
img.image = render
img.place(x=145, y=135)
self.downloadNum += 1
Label(self).grid(row=6, column =0)
Label(self).grid(row=7, column=0)
Label(self).grid(row=8, column=0)
Label(self).grid(row=9, column=0)
Label(self).grid(row=10, column=0)
pauseButton = Button(self, text="||", command = self.pause)
pauseButton.grid(row = 11, column = 1)
def pause(self):
pygame.mixer.pause()
root = Tk()
root.title("MP3 Player")
root.geometry("400x400")
app = Application(root)
root.mainloop()
try using:
pygame.mixer.music.pause()
instead of:
pygame.mixer.pause()

How to create Thread in GUI-application?

Problem:
I set up a image downloading GUI-application(tkinter) through unsplash API.
Every thing is working on. Not any error but when I run application so It's shows 'Not responding' cause Image downloading in background. How can I create Two threads. one will handle tkinter GUI and second will handle background image downloading process.
My code:
from tkinter import *
import requests
import os, pprint
from time import sleep
from threading import *
from urllib.request import urlretrieve
class Gui(Tk):
def __init__(self):
self.do_splash_call = False
Tk.__init__(self)
self.title('unsplash image download')
self.geometry('900x500')
# main canvas
main = Canvas(self, bg='#0099e6')
main.place(relx=0, rely=0, relwidth=1, relheight=1)
# frame1 for upper left
name_frame = Frame(main)
name_frame.place(relx=.1, rely=.1)
# name input and label
name_label = Label(name_frame, text='Image Name:')
name_label.pack(side=LEFT, pady=3)
self.name = Entry(name_frame, bd=0, font=2, width=23)
self.name.pack(side=RIGHT, pady=3)
# frame2 for upper right
page_frame = Frame(main)
page_frame.place(relx=.5, rely=.1, relwidth=.3)
# landing page
Label(page_frame, text='Landing page:').pack(side=LEFT, pady=3)
self.page = Spinbox(page_frame, from_=1, to=50, width=30)
self.page.pack(side=RIGHT, pady=3)
# frame3 for down left
size_frame = Frame(main)
size_frame.place(relx=.1, rely=.2)
# name input and label
size_label = Label(size_frame, text='Android, pc, tablet:')
size_label.pack(side=LEFT, pady=3)
self.size = Entry(size_frame, bd=0, font=2)
self.size.pack(side=RIGHT, pady=3)
# button
download = Button(main, bd=1, font=4, text='Download', width=10, command=lambda :self.splash())
download.place(relx=.6, rely=.2)
# output
self.output = Text(main, bd=2)
self.output.place(relx=0, rely=.5, relheight=1, relwidth=1)
# path to save images
save_frame = Frame(main)
save_frame.place(relx=.1, rely=.3, relwidth=.7)
Label(save_frame, text='Save:').pack(side=LEFT, padx=5)
self.save = Entry(save_frame, bd=1)
self.save.place(relx=.1, relwidth=1)
# insert path for save images
self.save.insert(0, str('c:\\users\\abc\\Desktop\\photos'))
def path(self):
if os.path.exists(self.save.get()):
os.chdir(self.save.get())
else:
os.mkdir(self.save.get())
os.chdir(self.save.get())
def splash(self):
self.do_splash_call = True
self.call_splash()
def call_splash(self):
if self.do_splash_call:
# getting input from user
image_name = self.name.get()
pages = self.page.get()
size = self.size.get()
# set the size of photos
if size == 'pc' or 'desktop':
size = 1080
orientation = 'landscape'
elif size == 'hd' or 'full hd' or 'clear' or 'normal' or 'HD':
size = 1500
orientation = 'landscape'
elif size == 'android' or 'mini' or 'mobile':
size = 400
orientation = 'portrait'
else:
size = 1500
orientation = 'landscape'
try:
api = f'''https://api.unsplash.com/photos/search?query=
{image_name}&resolution={size}&orientation=
{orientation}&client_id=API Key
&page={pages}&w=1500&dpi=2'''
res = requests.get(api).json()
for i in range(2):
url = res[i]['links']['download']
name_of_image = str(res[i]['alt_description'])
img_name = '_'.join(name_of_image[:40].split(' '))
# create folder for download images
self.path()
# print current images downloading
self.output.insert(INSERT, '\nDownloading img.... %s.png' % img_name)
self.output.tag_add('fine', '1.0', '3.0')
self.output.tag_config('fine', background='lightGreen', foreground='#196619')
# Downloading image in pc
urlretrieve(url, '%s.png' % img_name)
except Exception as e:
self.output.insert(INSERT, e)
self.output.tag_add('error', '1.0', '3.0')
self.output.tag_config('error', background='#ff4d4d', foreground='black')
print(e)
if __name__ == '__main__':
app = Gui()
app.mainloop()
I except:
There is a class and class inside there is method called splash() so How can I create Thread, one for constructor and second for splash() method ?
Example with thread and other changes or comments in code because there are mistakes.
I didn't change from tkinter import * because it would need more work. On some systems thread may not have access to GUI so self.output in call_spash may have problem but I didn't change it - too many works.
By the way: PEP 8 -- Style Guide for Python Code
from tkinter import * # PEP8 - don't use *
#import tkinter as tk
import requests
import os
import pprint # PEP8 - imports in separated lines
from time import sleep
# from threading import * # PEP8 - don't use *
import threading
from urllib.request import urlretrieve
class Gui(Tk):
def __init__(self):
#Tk.__init__(self)
super().__init__() # instead of Tk.__init__(self)
self.title('unsplash image download')
self.geometry('900x500')
self.do_splash_call = False
self.thread = None
# main canvas
main = Canvas(self, bg='#0099e6')
main.place(relx=0, rely=0, relwidth=1, relheight=1)
# frame1 for upper left
name_frame = Frame(main)
name_frame.place(relx=.1, rely=.1)
# name input and label
name_label = Label(name_frame, text='Image Name:')
name_label.pack(side=LEFT, pady=3)
self.name = Entry(name_frame, bd=0, font=2, width=23)
self.name.pack(side=RIGHT, pady=3)
# frame2 for upper right
page_frame = Frame(main)
page_frame.place(relx=.5, rely=.1, relwidth=.3)
# landing page
Label(page_frame, text='Landing page:').pack(side=LEFT, pady=3)
self.page = Spinbox(page_frame, from_=1, to=50, width=30)
self.page.pack(side=RIGHT, pady=3)
# frame3 for down left
size_frame = Frame(main)
size_frame.place(relx=.1, rely=.2)
# name input and label
size_label = Label(size_frame, text='Android, pc, tablet:')
size_label.pack(side=LEFT, pady=3)
self.size = Entry(size_frame, bd=0, font=2)
self.size.pack(side=RIGHT, pady=3)
# button
#download = Button(main, bd=1, font=4, text='Download', width=10, command=lambda :self.splash())
download = Button(main, bd=1, font=4, text='Download', width=10, command=self.splash) # no need lambda
download.place(relx=.6, rely=.2)
# output
self.output = Text(main, bd=2)
self.output.place(relx=0, rely=.5, relheight=1, relwidth=1)
# path to save images
save_frame = Frame(main)
save_frame.place(relx=.1, rely=.3, relwidth=.7)
Label(save_frame, text='Save:').pack(side=LEFT, padx=5)
self.save = Entry(save_frame, bd=1)
self.save.place(relx=.1, relwidth=1)
# insert path for save images
#self.save.insert(0, str('c:\\users\\abc\\Desktop\\photos'))
self.save.insert(0, 'c:\\users\\abc\\Desktop\\photos') # it is already string
def path(self):
# you could use `val = self.save.get()` once and later use `val`
#if os.path.exists(self.save.get()):
# os.chdir(self.save.get())
#else:
# os.mkdir(self.save.get())
# os.chdir(self.save.get())
val = self.save.get()
if not os.path.exists(val):
#os.mkdir(val) # it makes only first dir in path `dir1/dir2/dir3`
os.makedirs(val) # it makes all dirs in path `dir1/dir2/dir3`
#os.makedirs(val, exist_ok=True) # Python 3.7+, it doesn't need `os.path.exists`
os.chdir(val)
def splash(self):
#if not self.thread or not self.thread.is_alive(): # method without `self.do_splash_call`
if not self.do_splash_call:
print('[DEBUG] run splash')
self.do_splash_call = True
# getting input from user
image_name = self.name.get()
pages = self.page.get()
size = self.size.get()
self.thread = threading.Thread(target=self.call_splash, args=(image_name, pages, size) )
self.thread.start()
def call_splash(self, image_name, pages, size):
# set the size of photos
#if size == 'pc' or 'desktop': # wrong
#if size == 'pc' or size = 'desktop': # good
if size in ('pc', 'desktop'): # good
size = 1080
orientation = 'landscape'
#elif size == 'hd' or 'full hd' or 'clear' or 'normal' or 'HD': # wrong
elif size in ('hd', 'full hd', 'clear', 'normal', 'HD'):
size = 1500
orientation = 'landscape'
#elif size == 'android' or 'mini' or 'mobile': # wrong
elif size in ('android', 'mini', 'mobile'):
size = 400
orientation = 'portrait'
else:
size = 1500
orientation = 'landscape'
try:
api = f'''https://api.unsplash.com/photos/search?query=
{image_name}&resolution={size}&orientation=
{orientation}&client_id=API Key
&page={pages}&w=1500&dpi=2'''
res = requests.get(api).json()
print('[DEBUG] res:', res)
for i in range(2):
url = res[i]['links']['download']
name_of_image = str(res[i]['alt_description'])
img_name = '_'.join(name_of_image[:40].split(' '))
# create folder for download images
self.path()
# print current images downloading
self.output.insert(INSERT, '\nDownloading img.... %s.png' % img_name)
self.output.tag_add('fine', '1.0', '3.0')
self.output.tag_config('fine', background='lightGreen', foreground='#196619')
# Downloading image in pc
urlretrieve(url, '%s.png' % img_name)
except Exception as e:
self.output.insert('end', e)
self.output.tag_add('error', '1.0', '3.0')
self.output.tag_config('error', background='#ff4d4d', foreground='black') # you could define it once
print('[DEBUG] e:', e)
self.do_splash_call = False
if __name__ == '__main__':
app = Gui()
app.mainloop()

How to get value from command tkinter

This is probably a newbie question but I'm having issues figuring out how to get a value from a function, to be used as input in another.
I would also like to have some tips about code organization.
In this example I'm trying to get the filePath and outPut Folder path to be used in the function processFile.
Thank you
Code:
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import askdirectory
import PyPDF2
from PyPDF2 import PdfFileWriter, PdfFileReader
version = "v0.0.01"
root = Tk()
def window (main):
main.title("File Opener " + version)
width = main.winfo_width()
main.geometry('500x200')
numero = str(1)
def OpenFile():
fileName = askopenfilename(initialdir="C:/",
filetypes =(("PDF File", "*.pdf"),("All Files","*.*")),
title = "Select PDF File",
)
labelName = Label(text="File Path: " + fileName)
labelName.pack()
print(fileName)
return fileName
def outputFolder(): #Bug, label keeps adding paths
outPath = askdirectory()
labelName2 = Label(text="Output Folder: " + outPath)
labelName2.pack()
print(outPath)
return outPath
def processFile(inFile,outFolder):
''' print(fileName) get input name and output variables
print(outPath)'''
label = ttk.Label(root, text ="",foreground="black",font=("Helvetica", 16))
label.pack()
#Button Open-----------
button1 = Button (text = "Open File", command = OpenFile)
button1.pack()
#Button Start---------
buttonStart = Button (text = "Start Process", command = processFile)#give as parameter inputFile and link
buttonStart.place(height=50, width=100)
#Button Open-----------
button3 = Button (text = "Output Folder", command = outputFolder)
button3.pack()
#Menu Bar ----------------
menu = Menu(root)
root.config(menu=menu)
file = Menu(menu)
file.add_command(label = 'Open', command = OpenFile)
file.add_command(label = 'Exit', command = lambda:exit())
menu.add_cascade(label = 'File', menu = file)
window(root)
root.mainloop()
If you use the function in a variable the returned result from the function is stored in the variable.
def Function1(x):
return x*2
var1 = Function1(5)
Then var1 = 10.
But about your buttons, do you want to take input from the user that will be saved when the button is pressed or do you want the button to send a set value?
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import askdirectory
import PyPDF2
from PyPDF2 import PdfFileWriter, PdfFileReader
version = "v0.0.01"
root = Tk()
def window (main):
main.title("File Opener " + version)
width = main.winfo_width()
main.geometry('500x200')
main.configure(background = 'black')
numero = str(1)
#openFile
def OpenFile():
global fileName
fileName = askopenfilename(initialdir="C:/",
filetypes =(("PDF File", "*.pdf"),("All Files","*.*")),
title = "Select PDF File",
)
labelName = Label(text="File Path: " + fileName)
labelName.pack()
print(fileName)
return str(fileName)
#getOutputPath
def outputFolder(): #Bug, label keeps adding paths
outPath = askdirectory()
labelName2 = Label(text="Output Folder: " + outPath)
labelName2.pack()
print(outPath)
return outPath
#testFunct
def printFilename(inArg):
print(inArg)
x = OpenFile()
print (OpenFile())
lambda: printFilename(fileName)
#processRealDeal
def processFile(): #THIS IS THE MAIN FUNC
''' print(fileName) get input name and output variables
print(outPath)'''
print (OpenFile)
label = ttk.Label(root, text ="",foreground="black",font=("Helvetica", 16))
label.pack()
#Button Open-----------
button1 = Button (text = "Open File", command = OpenFile)
button1.pack()
#Button Start---------
buttonStart = Button (text = "Start Process", command = lambda: printFilename("Hello World!!!"))#give as parameter inputFile and link
buttonStart.place(height=50, width=100)
#Button Open-----------
button3 = Button (text = "Output Folder", command = outputFolder)
button3.pack()
#Menu Bar ----------------
menu = Menu(root)
root.config(menu=menu)
file = Menu(menu)
file.add_command(label = 'Open', command = OpenFile)
file.add_command(label = 'Exit', command = lambda:exit())
menu.add_cascade(label = 'File', menu = file)
window(root)
root.mainloop()
I cant see that you have declared the global fileName variabel outside the function.
I did this
from tkinter import *
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import askdirectory
import PyPDF2
from PyPDF2 import PdfFileWriter, PdfFileReader
version = "v0.0.01"
root = Tk()
fileName = "test"
def window (main):
main.title("File Opener " + version)
width = main.winfo_width()
main.geometry('500x200')
main.configure(background = 'black')
numero = str(1)
#openFile
def OpenFile():
global fileName
fileName = askopenfilename(initialdir="C:/",
filetypes =(("PDF File", "*.pdf"),("All Files","*.*")),
title = "Select PDF File",
)
labelName = Label(text="File Path: " + fileName)
labelName.pack()
test()
return str(fileName)
#getOutputPath
def test():
print(fileName)
def outputFolder(): #Bug, label keeps adding paths
outPath = askdirectory()
labelName2 = Label(text="Output Folder: " + outPath)
labelName2.pack()
print(outPath)
return outPath
#testFunct
def printFilename(inArg):
print(inArg)
x = OpenFile()
print (OpenFile())
lambda: printFilename(fileName)
#processRealDeal
def processFile(): #THIS IS THE MAIN FUNC
''' print(fileName) get input name and output variables
print(outPath)'''
print (OpenFile)
label = ttk.Label(root, text ="",foreground="black",font=("Helvetica", 16))
label.pack()
#Button Open-----------
button1 = Button (text = "Open File", command = OpenFile)
button1.pack()
#Button Start---------
buttonStart = Button (text = "Start Process", command = lambda: printFilename("Hello World!!!"))#give as parameter inputFile and link
buttonStart.place(height=50, width=100)
#Button Open-----------
button3 = Button (text = "Output Folder", command = outputFolder)
button3.pack()
#Menu Bar ----------------
menu = Menu(root)
root.config(menu=menu)
file = Menu(menu)
file.add_command(label = 'Open', command = OpenFile)
file.add_command(label = 'Exit', command = lambda:exit())
menu.add_cascade(label = 'File', menu = file)
window(root)
root.mainloop()
And the test function prints the chosen file. So the global variable is now containing the correct value.
So just declare it at the top and you will be able to retrieve the value

Categories