im trying to write a code that will tell you if the location is a file or directory. if its a file, then it will read the file. here is my code (ik its very bad, im sorry)
import os
import tkinter as tk
screen = tk.Tk()
screen.title("files and directories")
screen.geometry("300x100")
def FileDir():
path = location.get(1.0, "end-1c")
location.delete(1.0, tk.END)
if os.path.exists(path):
print("✔ - this location exists")
info_location = tk.Label(screen, text=f"location: {location}")
info_location.pack()
if os.path.isfile(path):
print("\tthis is a file")
type = 'file'
info_type = tk.Label(screen, text=f"type: {type}")
info_type.pack()
while True:
open_file = input("\nDo you want to read this file? ")
if open_file.lower() == 'yes':
with open(path) as file:
contents = file.read()
print(contents)
break
elif open_file.lower() == 'no':
print("goodbye!")
break
else:
print("invalid input")
continue
elif os.path.isdir(path):
print("\tthis is a directory")
type = 'directory'
info_type = tk.Label(screen, text=f"type: {type}")
info_type.pack()
else:
print("✘ - this location doesn't exist")
text = tk.Label(screen, text="Enter file/directory location: ")
text.pack()
location = tk.Text(screen, height = 1, width = 25)
location.pack()
enter_btn = tk.Button(screen, text="Enter", command=FileDir)
enter_btn.pack()
screen.mainloop()
so when putting the location of a string, everything works fine except that the location doesnt show and instead it shows ".!text". anyone know why?
location is a widget rather than a string. The string representation of a tkinter widget is its internal name. Thus, when you do text=f"location: {location}" you are creating a string that contains the name of the widget rather than the contents.
To display the contents you must fetch them from the widget. You're already doing that when you define path, so you just need to use {path} rather than {location}
text=f"location: {path}"
Related
I wanna make a program who edit the save of a game by only editing one specific line (line 6) on a .ini file but there is an error (TypeError: write() argument must be str, not tuple save.writelines(lines) )
from tkinter import *
from tkinter import filedialog
from pathlib import Path
# All important variables here to simplify reading my code
directory = None
path = None
save = None
room = None
def main():
print("\n[#] Select your game directory")
tk = Tk()
tk.geometry("0x0")
tk.wm_attributes('-toolwindow', 'True')
global directory
directory = filedialog.askdirectory(title="Select the game directory...")
path = Path(f"{directory}/save_data_main.ini")
if path.is_file(): # If save file exist
save = open(path, 'r+')
lines = save.readlines()
save.close()
print("\n[*] Your currently at the", lines[5])
print("[!] Please choose a number superior than 0 and inferior than 1000!")
room = input("[#] Change the room value : ")
lines[5] = "room=", str(room)
save = open(path, 'w+')
save.writelines(lines)
save.close()
print("[*] Value changed with success.")
else: # Error save file doesnt exist
print("\n[!] ERROR: Save file doesn't exist! Try to create a new Game.")
input("[*] Press Enter to continue...")
exit()
if __name__ == '__main__':
main()
I didnt write all the code tho, i tried to make something more simple to read and with only the important parts!
You should replace the line:
lines[5] = "room=", str(room)
With:
lines[5] = "room=" + str(room)
In python the "+" operator is used to concatenate string, with the "," you are creating a tuple.
lines[5] = "room=", str(room)
is the same that:
lines[5] = ("room=", str(room))
In this line:
lines[5] = "room=", str(room)
you are making element 5 of your list a tuple with the string 'room=' and the string of the value room.
try this:
line[5] = "room=" + str(room)
or do this:
lines[0] = f"room={str(room)}"
I need that when the button is clicked, the file_name variable is saved to a file. Please tell me how to fix my code:
window = tk.Tk()
window.title("Open")
window.geometry("600x400")
window.resizable(False, False)
file_name = ""
def openu():
global file_name
if file_name == "":
file_name = tfd.askopenfilename()
with open("Filen.json", "w") as file1:
json.dump(file_name, file1, indent=2, ensure_ascii=False)
os.startfile(file_name)
else:
with open("Filen.json", "r") as file1:
json.load(file1)
os.startfile(file_name)
if btn1["text"] == "":
btn1["text"] = file_name
btn1 = tk.Button(window, text="", command=openu)
btn1.place(x = 20, y = 25)
window.mainloop()
UPD:
When you click on the button, the program opens a dialog box that opens the file. A File.json is created. Everything is displayed, but one thing does not work. I need that when restarting the program, the buttons are not empty. I changed the code, putting the full one.
Here is the code. When the user opens the window, it loads the file path from the json file and automatically sets the button's text. When the user presses the button, it asks for a new file path name. More detailed explanations can be found in the comments in the code.
import tkinter as tk
import tkinter.filedialog as tfd
import json
import os
window = tk.Tk()
window.title("Open")
window.geometry("600x400")
window.resizable(False, False)
file_name = ""
def load_json():
global file_name
# Load the json file if it exists
if os.path.exists("Filen.json"):
with open("Filen.json") as file1:
contents = json.load(file1)
# If the json has a path in it, load the path to file_name
# Otherwise, set file_name to an empty string ""
if len(contents) > 0:
if contents[0] != "":
file_name = contents[0]
else:
file_name = ""
else:
file_name = ""
# Create the json file if it does not exist
else:
with open("Filen.json", "w") as file1:
json.dump([file_name], file1, indent=2, ensure_ascii=False)
def openu():
global file_name
# Load the json file
load_json()
# If file_name is still "", ask the user to input a file path
path = tfd.askopenfilename()
# If the user gave a path (did not hit Cancel), save path to file_name
# and set the button's label
if path != ():
file_name = path
btn1.config(text=file_name)
# Save file_name to the json file
with open("Filen.json", "w") as file1:
json.dump([file_name], file1, indent=2, ensure_ascii=False)
# Load the json file, and put the file name into the button's text
load_json()
btn1 = tk.Button(window, text=file_name, command=openu)
btn1.place(x = 20, y = 25)
window.mainloop()
Hello everyone viewing this question and trying to solve it!
I am making a GUI-based project planner where I need to add oroject name, requirements and steps to achieve which are then saved. I am also adding a feature to add files to it according to relevancy. But when I try to test it I get this: PermissionError: [Errno 13] Permission denied: '<project name>'. I don't know where I am going wrong despite of reading many such question. I have tried chmod but even that is not working. Here is the code:
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import askopenfilename
import os
WIN = Tk()
files =[]
def copy(src,dest):
os.chmod(dest, 0o777)
with open(src,'r') as f, open(dest,'w+') as f2:
f2.write(f)
def start(name):
os.startfile(name)
#<---Button functions--->
def Addfile():
global files
WIN.filename = askopenfilename(initialdir = "C:",title = "choose your file")
print(WIN.filename)
added_fr = Frame(text_box_files)
added_fr.pack()
f_name = Label(added_fr,text=WIN.filename)
f_name.pack()
#dest = shutil.copyfile(WIN.filename, destination)
files.append(WIN.filename)
f_b = Button(added_fr,text="Open",command=lambda x = WIN.filename: start(x))
f_b.pack()
def submit():
global files
name = name_ent.get()
req = text_box.get("1.0",END)
steps = text_box_step.get("1.0",END)
if name != "" and name not in os.listdir() and req != "" and steps != "":
os.mkdir(name)
with open(f"{name}\\req.txt","w") as f:
f.write(req)
with open(f"{name}\\steps.txt","w") as f2:
f2.write(steps)
os.mkdir(f"{name}\\main")
with open(f"{name}\\main\\main.py","w") as f3:
f3.write(f"#Main .py file of {name} project")
elif name in os.listdir():
messagebox.showerror("Project already exists", "A project with this name already exists! Try something else")
elif name=="" or req=="" or steps=="":
messagebox.showerror("Naming error", "Project name/steps/requirement can't be left blank")
print(files)
for fi in files:
copy(fi, name)
#<----Frames---->
head = Frame(WIN, padx=15,pady=10)
head.pack()
main_frame1 = Frame(WIN)
main_frame1.pack()
main_frame2 = Frame(WIN,highlightbackground="black" , highlightthickness=1)
main_frame2.pack()
name_frame = Frame(main_frame1,highlightbackground="black" , highlightthickness=1,padx=382,pady=3)
name_frame.pack()
requirements_frame = Frame(main_frame2)
requirements_frame.grid(row=0,column=0)
files_frame = Frame(main_frame2,highlightbackground="black", highlightthickness=1)
files_frame.grid(row=0,column=1)
#<----Title---->
title = Label(head, text="Project Planner", font=("Arial bold",18))
title.pack()
#<----Name-Frame---->
name_lb = Label(name_frame,text="Project name: ").grid(row=0,column=0,sticky="e")
name_ent = Entry(name_frame,width=20)
name_ent.grid(row=0,column=1)
#<----Requirements---->
requirements_lb = Label(requirements_frame, text="Requirements: ")
requirements_lb.pack()
text_box = Text(requirements_frame,width=100,height=5)
text_box.pack(side = TOP, expand = True, fill = BOTH)
#<----Step---->
step_lb = Label(requirements_frame,text="Steps/Ideas to solve: ")
step_lb.pack()
text_box_step = Text(requirements_frame,width=100,height=17)
text_box_step.pack(side = TOP, expand = True, fill = BOTH)
#<----Files---->
files_lb = Label(files_frame,text="Add files: ")
files_lb.pack()
text_box_files = Text(files_frame,width=20)
text_box_files.pack()
add = Button(files_frame,text="Add",command=Addfile)
add.pack(ipadx=30)
#<----Submit---->
submit = Button(WIN,text="Submit",command=submit)
submit.pack(ipadx=30,pady=2)
WIN.mainloop()
Also my operating system is Windows,
Please help.
I'm working on a little project for my friends and it's with python tkinter.
the code is
def run():
filename = filename_ent.get()
if filename == '':
# to show an error that boxes are empty
messagebox.showerror(
'File exists', 'File already exists, try some other name thas is not used before')
if os.path.exists(f'{filename}.txt'):
# to show an error if the file already exists
messagebox.showerror(
'File exists', 'File already exists, try some other name not used before')
else:
# to open the file for python
new = open(f'{filename}.txt', '+w', encoding='utf-8')
# to write the name and email inside the file
new.write(f'''Day of the week: {clicked}''')
eventl.config(text=f'Done :)!') # to change the label to the name
os.startfile(f'{filename}.txt') # to open the file in a new window
eventl = Label(root, text='What is the name of the event',font=('helvatica',14))
eventl.place(x=0,y=0)
lfilename = Label(root,text="What do you want to call the file?", font = ("helvatica, 14"))
lfilename.pack()
filename_ent = Entry(root)
filename_ent.pack(pady=10,padx=30)
clicked = StringVar()
drop = OptionMenu(root, clicked, "Monday", "Tuesday")
drop.pack(pady=10,padx=10)
b = Button(root, text='Done', command=run)
b.pack(pady=(10, 0))
root.mainloop()
Note: I'm using utf-8 because I'm also using Arabic inputs but that doesn't seem to be the problem since I tried removing it(this isn't the whole code).
It should be new.write(f'''Day of the week: {clicked.get()}''') instead of new.write(f'''Day of the week: {clicked}'''). Clicked is the just the StringVar() you have to access the value of it using the get() method.
Hope this helped, do let me know if any errors.
Cheers
I would like to validate the users choice of folder name in a gtk.FileChooser dialogue when creating a new folder.
I tried connecting to the dialogue 'response' signal, but it is already too late, the new folder will be written to disc.
Is there a way to achieve this other then validate the folder after it is written to disc?
Thanks to Mark... here is the code I'm using:
import gtk
def _newFolderDialog(currentFolder=None):
newDialog = gtk.FileChooserDialog(
title="Create new folder", parent=None,
action=gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER,
buttons= (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), backend=None)
newButton = newDialog.add_button(gtk.STOCK_NEW, gtk.RESPONSE_OK)
if currentFolder is not None:
newDialog.set_current_folder(currentFolder)
newButton.connect("pressed", validateChoice, newDialog)
response = newDialog.run()
if response == gtk.RESPONSE_OK:
newFolder = newDialog.get_filename()
newDialog.destroy()
return newFolder
elif response == 1: # Validation was not satisfied
msg = gtk.MessageDialog(parent=None, flags=gtk.DIALOG_MODAL,
type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK,
message_format="Try again!")
msg.run()
msg.destroy()
current_folder = newDialog.get_current_folder()
newDialog.destroy()
return _newFolderDialog(current_folder)
elif response == 2: # Ok button was pressed, but with no entry
current_folder = newDialog.get_current_folder()
newDialog.destroy()
return _newFolderDialog(current_folder)
elif response == gtk.RESPONSE_CANCEL:
newDialog.destroy()
return None
def validateChoice(button, dialog):
newFolder = dialog.get_filename()
if newFolder is None: # The cursor was in the empty text entry box
dialog.response(2)
else:
# If cursor is selecting a folder, lets unselect it, we are intereste
# in the value in the entry text box.
dialog.unselect_filename(newFolder)
newFolder = dialog.get_filename()
if newFolder is None: # A folder was selected but empty text entry box
dialog.response(2)
## do some validation, in this case the folder has to start with "/home"
elif not newFolder.startswith("/home"):
dialog.response(1)
else:
dialog.response(gtk.RESPONSE_OK)
newFolder = _newFolderDialog()
print newFolder
I can see a couple ways of doing this.
One, simply write your own response id handler instead of using gtk.RESPONSE_OK (which to the widget means create the folder). If you do it this way you'll be responsible for actually creating the folder after validation (os.path.mkdir).
Two, you could override the click on the "new" button:
import gtk
def new_button_pressed(widget, data=None):
## data is a reference to the dialog widget
## do some validation, in this case the folder has to start with "/home"
if not(data.get_filename().startswith("/home")):
## force cancel response
print "failed validation..."
data.response(gtk.RESPONSE_CANCEL)
else:
print "success validation..."
data.response(gtk.RESPONSE_OK)
newDialog = gtk.FileChooserDialog(
title="Create new folder", parent=None,
action=gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER,
buttons= (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), backend=None)
new_button = newDialog.add_button(gtk.STOCK_NEW, gtk.RESPONSE_OK)
new_button.connect("pressed", new_button_pressed, newDialog)
newDialog.run()