Using tkinter's folder choosing dialog box twice - python

At the start of my code, I let the user choose a file and store its path in a text file. Here is the function for that:
def choose_folder():
root = tk.Tk()
root.withdraw()
global DIR
DIR = filedialog.askdirectory()
global settings_file # Somehow works without this line despite being declared in main
with open(settings_file, "w") as sf:
sf.write(DIR)
Now, I want to let the user change the folder. In the main loop, the user chooses an option each time. Option 4 is to change the directory. Here is my code to change it:
elif user_input == 4:
open(settings_file, "w").close() # Clear the settings file
choose_folder()
The problem is, that for some reason the folder choosing dialog box will not open the second time. I've already checked and the code reaches the choose_folder() function but stops running on filedialog.askdirectory() (the screen flickers for a second which means that something happens but doesn't open the dialog box). What causes this to happen and how can I fix it?
EDIT: Here's the code snippet (I have also slightly changed choose_folder()):
import tkinter as tk
from tkinter import filedialog
import os
#other imports
def prompt_continue() -> bool:
choice = input("Do you want to continue (y/n)? ")[0].lower()
while choice != 'y' and choice != 'n':
choice = input("Invalid Input. ")[0].lower()
return choice == 'y'
def choose_folder():
root = tk.Tk()
root.withdraw()
global DIR
DIR = filedialog.askdirectory()
while not os.path.isdir(DIR):
print("Please choose a folder.")
DIR = filedialog.askdirectory()
while os.listdir(DIR):
print("Please choose an empty folder.")
DIR = filedialog.askdirectory()
with open(settings_file, "w") as sf:
sf.write(DIR)
if __name__ == "__main__":
DIR = ""
settings_file = os.path.expanduser('~/Documents/flagdir.txt')
if os.path.isfile(settings_file): # if settings file exists
if os.stat(settings_file).st_size == 0: # if settings file is empty
choose_folder()
else:
choose_folder()
with open(settings_file, 'r') as file:
DIR = file.read()
user_continue = True
total = 0
while user_continue:
print("Choose option:")
print("[1] Download n random flags")
print("[2] Enter 2 countries and download their mashup")
print("[3] Clear the flags folder")
print("[4] Change the flags folder path")
print("[5] Print the flags folder path")
print("[6] Exit")
user_input = int(input())
while user_input < 1 or user_input > 6:
user_input = int(input("Invalid Input."))
if user_input == 1:
# working code
elif user_input == 2:
# working code
elif user_input == 3:
# working code
elif user_input == 4:
open(settings_file, "w").close()
choose_folder()
elif user_input == 5:
# working code
else:
break
user_continue = prompt_continue()
print("Bye!")

Related

I'm having troubles using pyinstaller

I have a simple python script (meant to be run in terminal) that I want to compile, or at least make executable for PCs without python installed, so when I make an EXE with pyinstaller --onefile --nowindow random.py and send it over to my friend his windows defender stops it and even after getting around it at the list = open(fileName,'w+') it crashes. I have no idea why because it runs perfectly using python random.py
Here's the code:
import glob
import os
import random
a = True
while a == True:
x = input('Do you want to make a new savefile? (y/n): ')
if x == 'y':
fileName = input('\nWhat do you want its name to be? (put .txt at the end)\n')
list = open(fileName, 'w+')
addToList = True
a = False
elif x == 'n':
svfs = glob.glob("*.txt")
print('\nWhich save file do you want to use?\n', svfs)
fileName = input()
a = False
else:
print('Please give a valid answer (\"y\" for yes, \"n\" for no)')
if x == 'n':
print('\nDo you want to overwrite the selected savefile?')
if os.path.getsize(str(fileName)) == 0:
print('(The savefile is empty)')
else:
print('(The savefile isn\'t empty)')
b = input('(y/n): ')
if b == 'y':
list = open(fileName, 'w')
addToList = True
elif b == 'n':
addToList = False
else:
print('Please give a valid answer (\"y\" for yes, \"n\" for no)')
if addToList == True:
print("\nAdd items to the list:\n(type !done when you're done)")
while addToList == True:
string = input("\t")
if string == "!done":
addToList = False
else:
list.writelines([string, '; '])
list.close()
print(random.choice(open(str(fileName), 'r').readline().split('; ')))
input()

Menu interferring with save prompt

I am experiencing an issue where if I introduce a user choice menu into my code, a function that produces a save dialog will not appear. If I comment out the menu function then everything works.
A sample of my code is below. I have ripped out a lot of other functions so only the minimum is presented below and will not make any sense but the code does work when commenting out the save_forms def.
I've only been at this for a few weeks so any constructive criticism would be appreciated.
import time
import sys
from tkinter import *
from tkinter import filedialog as fd
global OU
global tempdir
global fs
def menu():
print("[1] Number 1")
print("[2] Number 2")
print("[0] Exit")
ou_option = int(input("Enter a number: "))
if ou_option == 1:
print("Number 1 selected")
OU = str("Number1")
elif ou_option == 2:
print("Number 2 selected")
OU = str("Number2")
elif ou_option == 0:
print("Exiting")
time.sleep(1)
sys.exit()
else:
print("Invalid number. Try again...")
menu()
def save_forms():
tk2 = Tk()
tk2.withdraw()
fs = fd.askdirectory(title='Select output folder')
if not fs:
print('User Cancelled')
time.sleep(1)
sys.exit()
else:
print('Saving...')
menu()
print("Saving Form")
save_forms()
Using tk1.attributes("-topmost", True) brings the dialog to the front.
Thanks Bill for the point in the right direction.

First if statement in while loop not working

I am a beginner and I can't for the life of me find the error.
When I run this function and input '2' it continues and works properly. When I enter '3' it prints the proper message and loops back around to the top...but when I enter '1', this is the output:
Hmm... Given the options "1" and "2," you chose "1"!!!!???
try again.
The code for option 1 and option 2 are exactly the same (I copy and pasted), but the first option doesn't work. I even tried switching the values around, so that the boolean statements were flipped (the first option read, if file_option == '2' and the second read if file_option == '1') and no luck. I have determined that it is the first option that is always broken, but I do not understand why.
def file_path(location):
home = os.path.expanduser('~')
download_path = os.path.join(home, location)
return download_path
def file_path_chooser():
clear()
file_option = None
while file_option not in ('1','2'):
file_option = input('''
Choose from the following locations:
Note: You will have the option to choose folders inside of whatever you choose.
type '1' for Documents
type '2' for Desktop
response: ''')
if file_option == '1':
clear()
dir_contents_list = os.listdir(file_path('Desktop'))
folder_list = []
p0 = '''
Please pick from the following locations:
'''
for item in dir_contents_list:
if '.' not in item:
folder_list.append(item)
p1 =''
for folder in folder_list:
folders_text = '''
type '{num}' to save the file in {folder}'''.format(folder=folder, num=folder_list.index(folder))
p1 += folders_text
print(p0+p1)
if file_option == '2':
clear()
dir_contents_list = os.listdir(file_path('Desktop'))
folder_list = []
p0 = '''
Please pick from the following locations:
'''
for item in dir_contents_list:
if '.' not in item:
folder_list.append(item)
p1 =''
for folder in folder_list:
folders_text = '''
type '{num}' to save the file in {folder}'''.format(folder=folder, num=folder_list.index(folder))
p1 += folders_text
print(p0+p1)
else:
clear()
print('Hmm... Given the options "1" and "2," you chose ' + '"'+ file_option.upper()+'"!!!!???\n\ntry again.')
time.sleep(1)
def clear():
# for windows
if name == 'nt':
_ = system('cls')
# for mac and linux (note: for these, os.name = 'posix)
else:
_ = system('clear')
I changed the if file_option == "2" to elif file_option == "2"
def file_path(location):
home = os.path.expanduser('~')
download_path = os.path.join(home, location)
return download_path
def file_path_chooser():
clear()
file_option = None
while file_option not in ('1','2'):
file_option = input('''
Choose from the following locations:
Note: You will have the option to choose folders inside of whatever you choose.
type '1' for Documents
type '2' for Desktop
response: ''')
if file_option == '1':
clear()
dir_contents_list = os.listdir(file_path('Desktop'))
folder_list = []
p0 = '''
Please pick from the following locations:
'''
for item in dir_contents_list:
if '.' not in item:
folder_list.append(item)
p1 =''
for folder in folder_list:
folders_text = '''
type '{num}' to save the file in {folder}'''.format(folder=folder, num=folder_list.index(folder))
p1 += folders_text
print(p0+p1)
elif file_option == '2':
clear()
dir_contents_list = os.listdir(file_path('Desktop'))
folder_list = []
p0 = '''
Please pick from the following locations:
'''
for item in dir_contents_list:
if '.' not in item:
folder_list.append(item)
p1 =''
for folder in folder_list:
folders_text = '''
type '{num}' to save the file in {folder}'''.format(folder=folder, num=folder_list.index(folder))
p1 += folders_text
print(p0+p1)
else:
clear()
print('Hmm... Given the options "1" and "2," you chose ' + '"'+ file_option.upper()+'"!!!!???\n\ntry again.')
time.sleep(1)
def clear():
# for windows
if name == 'nt':
_ = system('cls')
# for mac and linux (note: for these, os.name = 'posix)
else:
_ = system('clear')

Splitting a Python Filename [duplicate]

This question already has answers here:
Extract file name from path, no matter what the os/path format
(22 answers)
Closed 4 years ago.
I am trying to create an anagram program quiz. One of the things I have done is having one central method of reading from a specified file dependant on which option the user has chosen rather than having to repeat the code. However, when trying to save the info to file, the variable saved has the pathfile saved inside it. How can I split it so that it will only save the name of the file (i.e, name of the quiz) that has been opened?
def main():
name = input("Please Enter your name to begin")
print("Hi",name,"Welcome to the Computer Science Quiz")
user_choice = menu()
option = choice(user_choice)
option, counter = questions(option)
update_file(name, option, counter)
def menu():
print("Select from the following categories:")
print("1 for System's Architecture, 2 for Memory, 3 for Storage or 4 for Network Topologies")
choice = int(input("choose option"))
if choice >0 and choice<=4: ## range check
print("you have chosen",choice,)
else:
print("This is an invalid number")
menu()
return choice
def choice(user_choice):
if user_choice == 1:
systems = open('systems.csv','r')
return systems
elif user_choice ==2:
memory = open('memory.csv','r')
return memory
else:
storage = open('storage.csv','r')
return storage
def questions(option):
counter = 0
for line in option:
anagrams = (line.rstrip("\n").split(","))
question = anagrams[0]
answer = anagrams[1]
print (question)
print (answer)
guess = input("Enter your guess")
if guess == answer:
print("Well Done")
counter = counter + 1
else:
print("oops")
print("You have scored",counter,"correctly")
return option,counter
def update_file(name, option, counter):
string_counter = (str(counter))
string_option = (str(option))
results = [name,",",string_counter,",",string_option,"\n"]
file = open('results.csv','a')
file.writelines(results)
file.close()
This is what it shows when the file is saved for the option variable:
<_io.TextIOWrapper name='storage.csv' mode='r' encoding='cp1252'>
You can remove the path from filename with this function:
import os
print(os.path.basename(file_name_with_path))

I am having trouble with adding items to my list in python

Just like the title says I am having trouble adding items to a list for some reason. I am sure it is something simple, but just to make sure.
fnamesfile = open('fnames.txt','w')
global fnames
fnames = ['spanish.db', 'biology.db', 'dictionary.db']
def choose():
global filename
print "\nEXISTING FILES:"
for i in fnames:
print i
print "\nFOR NEW FILE ENTER NEW NAME:"
choice = raw_input('Open: ')
choicedb = "%s.db" % choice
if choicedb in fnames:
filename = shelve.open(choicedb)
else:
choice = raw_input("ARE YOU SURE YOU WANT TO MAKE NEW FILE?[y/n] ")
if choice == 'y':
fnames.append(choicedb)
filename = shelve.open(choicedb)
elif choice == 'n':
choose()
It looks like you need to both import the shelves library and actually make a call to your function.
import shelve
fnames = ['spanish.db', 'biology.db', 'dictionary.db']
def choose():
print fnames # for debugging
global filename
print "\nEXISTING FILES:"
for i in fnames:
print i
print "\nFOR NEW FILE ENTER NEW NAME:"
choice = raw_input('Open: ')
choicedb = "%s.db" % choice
if choicedb in fnames:
filename = shelve.open(choicedb)
else:
choice = raw_input("ARE YOU SURE YOU WANT TO MAKE NEW FILE?[y/n] ")
if choice == 'y':
fnames.append(choicedb)
filename = shelve.open(choicedb)
elif choice == 'n':
choose()
print fnames # for debugging
choose()
The first and last print statements I am leaving in there for you so you can see it working, but you should remove them after you are satisfied that it's working.

Categories

Resources