Only one file decrypting in for loop - python

I have an issue with my program.
Whenever I encrypt multiple files, it works flawlessly; when I decrypt the files however, it fails pretty hard. No errors or anything.
The issue is just;
Only one file decrypts, no more. The rest of the files do look decrypted, but at the same time ?not?
Here is an example image of what shows when I decrypted a text file with pi to 1m digits. This only happens when decrypting multiple files.
Finally, here is the code. Big thanks to anyone willing to be helpfull!!! :)
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
import sys
import os.path
from tkinter import *
import tkinter.filedialog as fd
from tkinter import ttk
from tkinter import messagebox
from PIL import ImageTk,Image
from os import startfile
# Just some path defining stuff
user_profile = os.environ['USERPROFILE']
user_desktop = user_profile + "\\Documents"
os.chdir(sys.path[0])
save_path = f'{sys.path[0]}/TestEncrypted'.replace("\\","/")
save_path2 = f'{sys.path[0]}/TestDecrypted'.replace("\\","/")
# Create directories for encrypted/decrypted files
try:
os.mkdir(save_path)
except:
print(f'Directory: {save_path} already exists')
try:
os.mkdir(save_path2)
except:
print(f'Directory: {save_path2} already exists')
def padkey(key):
global oldkey
oldkey = key
while len(key)% 16 != 0:
key+= " "
return key
def encrypt1():
"""
Loops over files for encryption.
"""
newkey = padkey('testpass').encode('UTF-8')
cipher = AES.new(newkey,AES.MODE_CBC)
# Create for loop here!!!
filez = fd.askopenfilenames(parent=root, title='Choose files to encrypt',initialdir = user_desktop)
for filename in filez:
try:
with open(filename, 'rb') as f:
rfile = f.read()
f.close()
except:
messagebox.showerror("ITExtra Popup", "You didn't select a file")
ciphertext = cipher.encrypt(pad(rfile, AES.block_size))
encryptfilename = filename.split('/')[-1]+'.ENCRYPTED'
completeName = os.path.join(save_path, encryptfilename).replace("\\","/")
print(completeName)
with open(completeName,'wb') as c_file:
c_file.write(cipher.iv)
c_file.write(ciphertext)
c_file.close()
label2=Label(root,text=(save_path+"/"+encryptfilename).replace('\\','/').lower(),font='Helvetica 13 bold italic',fg='BLUE',bg='black').place(relx=0,rely=0.88)
return
def decrypt1():
"""
Loops over files for decryption.
"""
faildec = 0
succdec = 0
filez2 = fd.askopenfilenames(parent=root, title='Choose files to decrypt',initialdir = save_path)
for decryptfilename in filez2:
newkey = padkey('testpass').encode('UTF-8')
# Decrypt file
try:
with open(decryptfilename,'rb') as c_file:
iv = c_file.read(16)
ciphertext = c_file.read()
c_file.close()
except:
faildec +=1
cipher = AES.new(newkey,AES.MODE_CBC, iv)
rfile = unpad(cipher.decrypt(ciphertext),AES.block_size)
# Input extension and save file
filename = decryptfilename.split('/')[-1].replace('.ENCRYPTED', '')
completeName2 = os.path.join(save_path2, filename)
with open(completeName2, 'wb') as writefile:
writefile.write(rfile)
writefile.close()
label2=Label(root,text=(save_path2+"/"+filename).replace("\\","/").lower(),font='Helvetica 10 bold italic',fg='BLUE',bg='black').place(relx=0,rely=0.88)
succdec +=1
response2 = messagebox.askyesno("ITExtra Popup", f"""Do you want to open the 'Decrypted' directory?\n{save_path2}
Successful decryptions = {succdec}
Failed decryptions = {faildec}
""")
if response2 == 1:
startfile(save_path2)
return
print(sys.path[0])
print(save_path)
print(save_path2)
print(user_desktop)
root = Tk()
w = 850 # width for the Tk root
h = 310 # height for the Tk root
ws = root.winfo_screenwidth() # width of the screen
hs = root.winfo_screenheight() # height of the screen
x = (ws/2) - (w/2)
y = (hs/3) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
frame1=LabelFrame(root,bd=0,bg='#000000')
but1 = Button(frame1, text="ENCRYPT file", padx=30, pady=10, bg="#1f1f1f",fg="red",font='Helvetica 15 bold', command=encrypt1,relief=FLAT)
but2 = Button(frame1, text="DECRYPT file", padx=30, pady=10, bg="#1f1f1f",fg="green",font='Helvetica 15 bold', command=decrypt1,relief=FLAT)
but1.grid(row=2,column=0,padx=1,pady=5) # Encrypt FILE #
but2.grid(row=2,column=2,pady=5) # Decrypt FILE #
frame1.place(relx=0.20,rely=0.5)
root.mainloop()
Edit
Removed except statements for debugging purposes.

Related

Python add watermark to pdf files

I wrote code to add watermark to pdf files however, the resulting files do not contain the watermark.
import os
import io
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
folder_path = 'D:/pdf/input/'
output_folder = 'D:/pdf/output/'
image_path = 'D:/pdf/watermark.jpg'
x, y = 50, 50
page_number = 1
if not os.path.exists(output_folder):
os.makedirs(output_folder)
for pdf_file in os.listdir(folder_path):
if pdf_file.endswith(".pdf"):
pdf_reader = PdfReader(open(os.path.join(folder_path, pdf_file), "rb"))
pdf_writer = PdfWriter()
for page_num in range(len(pdf_reader.pages)):
pdf_page = pdf_reader.pages[page_num]
pdf_writer.add_page(pdf_page)
if page_num == page_number - 1:
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.drawImage(image_path, x, y)
can.save()
packet.seek(0)
new_pdf = PdfReader(packet)
pdf_page.merge_page(new_pdf.pages[0])
with open(os.path.join(output_folder, pdf_file), "wb") as output_file:
pdf_writer.write(output_file)
print("Image added to the specified page of all pdf files and saved in the output folder.")
I've tried changing the image position and page number, but still no effect. I expect watermark to be added at a specific place in the pdf file.
FIXED
import os
import io
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
folder_path = 'D:/pdf/pliki/'
output_folder = 'D:/pdf/output/'
sign_path = 'D:/pdf/obraz/podpis.png'
x_position = 300
y_position = 260
width = 150
height = 150
if not os.path.exists(output_folder):
os.makedirs(output_folder)
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.drawImage(sign_path, x_position, y_position, width, height, [112,113,112,113,112,113])
can.save()
packet.seek(0)
new_pdf = PdfReader(packet)
for pdf_file in os.listdir(folder_path):
if pdf_file.endswith(".pdf"):
pdf_reader = PdfReader(open(os.path.join(folder_path, pdf_file), "rb"))
pdf_merged = pdf_reader.pages[0]
pdf_merged.merge_page(new_pdf.pages[0])
pdf_writer = PdfWriter()
for i in range(len(pdf_reader.pages)):
if i == 0:
pdf_writer.add_page(pdf_merged)
else:
pdf_writer.add_page(pdf_reader.pages[i])
with open(os.path.join(output_folder, pdf_file), "wb") as output_file:
pdf_writer.write(output_file)
print("Watermark added to the specified page of all pdf files and saved in the output folder.")

Why do these buttons open the same file regardless of which on I select?

I'm making a pdf 'date checker' in Python which tells me if every page of the pdf has tomorrows date at the top (for checking newspapers as part of my job).
So far so good until I attempted to put it all into a GUI, the buttons display the correct filename, but only open and check the last file in he list the buttons were generated from 'Files[i]'.
Can anybody figure out from my horrible nooby code why this is happening? please excuse the mess (I'm new) :)
Here is my ugly code :) I think the issue is either where I open the file using
'with open(files[i])' or 3rd line from the bottom where the buttons are created.
Any help would be greatly appreciated, thank you.
import os, glob
import fileinput
import tkinter as tk
import dateutil
import datetime
from dateutil.relativedelta import *
from dateutil.easter import *
from dateutil.parser import *
from dateutil.rrule import *
import PyPDF2
from PyPDF2 import PdfReader
from datetime import datetime, timedelta
from tkinter import *
folder_path = 'C:users/axlra/documents/datechecker'
for filename in glob.glob(os.path.join(folder_path, '*.pdf')):
with open(files[i], 'r') as f:
text = f.read()
print (files[i])
print (len(text))
def checknow():
tomorrow = (datetime.now() + timedelta(days=1)).strftime("%d-%m-%Y")
file = open(files[i], 'rb')
reader = PdfReader(files[i])
total = len(reader.pages)
for x in range(total+1):
if x > total: file.close()
page = reader.pages[0]
found = False
text = (page.extract_text())
parts = []
def visitor_body(text, cm, tm, fontDict, fontSize):
y = tm[5]
if y > 1600 and y < 10000:
parts.append(text)
page.extract_text(visitor_text=visitor_body)
text_body = "".join(parts)
#print(text_body)
word = text_body
word=word[22:-1]
#print(word)
prodate = parse(word)
str_date = prodate.strftime("%d-%m-%Y")
print(str_date)
print(files[i])
if tomorrow in str_date:
found = True
if found:
#print(x)
print("Tomorrow's date was found on page"+ " "+str(x))
else:
#print(x)
print("Tomorrow's date was NOT found on page"+ " "+str(x))
location = os.getcwd() # get present working directory location here
counter = 0 #keep a count of all files found
files = [] #list to store all pdf files found at location
for file in os.listdir(location):
try:
if file.endswith(".pdf"):
print ("pdf file found:\t", file)
files.append(str(file))
counter = counter
except Exception as e:
raise e
print ("No files found here!")
root = Tk()
btn = [] #creates list to store the buttons ins
for i in range(counter): #this just popultes a list as a replacement for the actual inputs for troubleshooting purposes
files.append(str(i))
for i in range(len(files)): #this says for *counter* in *however many elements there are in the list files*
#the below line creates a button and stores it in an array we can call later, it will print the value of it's own text by referencing itself from the list that the buttons are stored in
btn.append(Button(root, text=files[i], command=checknow))
btn[i].pack() #this packs the buttons
root.mainloop()
Based off the given solutions, this is the working code, the solution was to completely get rid of the 'i list' and just use file_path:
import os
import tkinter as tk
from tkinter import messagebox
import os, glob
import fileinput
import tkinter as tk
import dateutil
import datetime
from dateutil.relativedelta import *
from dateutil.easter import *
from dateutil.parser import *
from dateutil.rrule import *
import PyPDF2
from PyPDF2 import PdfReader
from datetime import datetime, timedelta
from tkinter import *
import re
location = os.getcwd()
counter = 0
files = []
for file in os.listdir(location):
try:
if file.endswith(".pdf"):
print ("pdf file found:\t", file)
files.append(str(file))
counter = counter
except Exception as e:
raise e
print ("No files found here!")
tomorrow = (datetime.now() + timedelta(days=-1)).strftime("%A,%B%e")
tomorrow = tomorrow.replace(" ", "")
tomorrow2 = (datetime.now() + timedelta(days=-1)).strftime("%d.%m.%Y")
tomorrow2 = tomorrow.replace(" ", "")
tomorrow3 = (datetime.now() + timedelta(days=-1)).strftime("%A%e%B%Y")
tomorrow3 = tomorrow.replace(" ", "")
tomorrow4 = (datetime.now() + timedelta(days=-1)).strftime("%A,%B%e")
tomorrow4 = tomorrow.replace(" ", "")
tomorrow5 = (datetime.now() + timedelta(days=-1)).strftime("%A,%e%B")
tomorrow5 = tomorrow.replace(" ", "")
def open_pdf(file_path):
file = open(file_path, 'rb')
reader = PdfReader(file)
total = len(reader.pages)
for x in range(total):
if x > x: file.close()
page = reader.pages[x]
text = (page.extract_text())
text = text.replace(" ", "")
#print(text)
substring = tomorrow
first_index = text.find(substring)
if first_index != -1:
second_index = text.find(substring, first_index + len(substring))
if second_index != -1:
print("Tomorrows date "+ tomorrow+ " appears twice on page"+ " "+str(x).format(substring))
else:
print("Tomorrows date "+ tomorrow+ " appears only once on page"+ " "+str(x)+" -".format(substring))
else:
print("Tomorrows date "+ tomorrow+ " does not appear on page"+ " "+str(x)+" ---".format(substring))
def create_buttons(directory):
for filename in os.listdir(directory):
if filename.endswith(".pdf"):
file_path = os.path.join(directory, filename)
button = tk.Button(root, text=filename, command=lambda f=file_path: open_pdf(f))
button.pack()
root = tk.Tk()
create_buttons(os.getcwd())
root.mainloop()
The basic answer is that at the end of for i in range(len(files)) the i does not get dereference like it does in some languages. A simple test to do is that this will give you an i of 2.
for i in range(3):
pass
print(i)
So when you call checknow() the referenced file would be the last file in files since your i doesn't change after the loop.
Something I've done in the past is create a class encompassing it so that each one holds to their own references. I did it without subclassing the tkinter class, but you could. A sample for an idea of what I did is
class FileButton:
def checknow(self):
file_name = self._file_name
#as an example of how you can reference the file_name.
#you can also do this by doing self._button.cget("text") and not have to store file_name
pass
def __init__(self, root, file_name):
self._root = root
self._file_name = file_name
self._button = tkinter.Button(root, text=file_name, command=self.checknow)
self._button.pack()
for i in range(len(files)):
btn.append(FileButton(root, files[i]))
I haven't tested this particular code, and my previous uses were more for labels and entries, but the principle of it was the same and I can confirm that using the callback in this manner worked. Also, if you don't need to reference the buttons anymore you don't have to append them to the btn list either.

How to use open function with path include space

I'M try to make a program that works with drag file into gui and create a hash code for it. But if path of file has space in it, then it goes error. How can i fix this
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\c9947515\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\c9947515\Desktop\Phyton\pythonProject1\dosya hash.py", line 19, in on_drop
with open(file_path, "rb") as file:
^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 22] Invalid argument: '{C:/Users/c9947515/Desktop/Wire Text.txt}'
import tkinterdnd2 as tk
import tkinter as tk2
import hashlib
root = tk.Tk()
root.title("File Hash Calculator")
root.geometry("400x150")
root.drop_target_register(tk.DND_FILES)
def on_drop(event):
file_path = event.data
# Dosya yolunu oku ve dosya içeriğini oku
with open(file_path, "rb") as file:
data = file.read()
# Dosya içeriğine göre SHA1 değerini hesapla
sha1_hash = hashlib.sha1(data).hexdigest()
# SHA1 değerini inputbox'a yazdır
input_box.insert(0, sha1_hash)
# Dosya sürükleyip bırakıldığında tetiklenecek fonksiyonu ata
root.dnd_bind("<<Drop>>", on_drop)
# Açıklama yazısı oluştur
label = tk2.Label(root, text="Drag and drop a file to calculate its SHA1 hash:")
label.pack()
# Giriş alanı oluştur
input_box = tk2.Entry(root)
input_box.pack()
# Pencerenin çalışmasını sağla
root.mainloop()
It is added by the underlying TCL interpreter when there are spaces in the string. You can remove them using .strip("{}"):
file_path = event.data.strip("{}")
{ and } are being added to your paths.
If you use file_path = file_path.replace("{", "").replace("}", "")
then it will not handle files with { or } anywhere in the filename. Use removeprefix and removesuffix instead to avoid this problem.
This will work:
import tkinterdnd2 as tk
import tkinter as tk2
import hashlib
root = tk.Tk()
root.title("File Hash Calculator")
root.geometry("400x150")
root.drop_target_register(tk.DND_FILES)
def on_drop(event):
if event.data.startswith('{') and event.data.endswith('}'):
file_path = event.data.removesuffix('}').removeprefix('{')
else:
file_path = event.data
# Dosya yolunu oku ve dosya içeriğini oku
with open(file_path, "rb") as file:
data = file.read()
# Dosya içeriğine göre SHA1 değerini hesapla
sha1_hash = hashlib.sha1(data).hexdigest()
# SHA1 değerini inputbox'a yazdır
input_box.insert(0, sha1_hash)
# Dosya sürükleyip bırakıldığında tetiklenecek fonksiyonu ata
root.dnd_bind("<<Drop>>", on_drop)
# Açıklama yazısı oluştur
label = tk2.Label(root, text="Drag and drop a file to calculate its SHA1 hash:")
label.pack()
# Giriş alanı oluştur
input_box = tk2.Entry(root)
input_box.pack()
# Pencerenin çalışmasını sağla
root.mainloop()

How can i detect if a file has already been opened in python

I hope you can help me, I'm new on python.
I am making a program in python with tkinter that requires opening a file and then converting it.
My problem is the conditional, because I need that when pressing the "Convert file" button it checks if the file has been selected first and if not, it shows a message that says "No file has been opened".
I think the problem is in the return opened_file_path. How can I make the string variable of the file path available to any function?
Here is my code, thank you.
from tkinter import filedialog
from tkinter import messagebox
from tkinter import *
import os
import re
window = Tk()
window.title("Blank-Space UXD deleter (beta)")
window.geometry('400x50')
def open_file():
opened_file_path=filedialog.askopenfilename(initialdir = "/",
title = "Select files",filetypes = (("TXT files","*.txt"),
("All files","*.*")))
return opened_file_path
def convert_file():
if opened_file_path == "":
messagebox.showinfo(message="No file has been opened", title="Imposible to convert")
else:
file_name = opened_file_name
file_name_mod = file_name.replace(".txt", "")
file_name_mod = file_name_mod + "m.txt"
mod_file = open(file_name_mod, 'w')
raw_file = open(file_name, 'r')
for x in raw_file:
xf = re.sub(' +', ' ', x)
xf = xf.lstrip()
mod_file.write(xf)
print(x)
print(xf)
Button(text="Open file",command=open_file).place(x=10,y=10)
Button(text="Convert file",command=convert_file).place(x=150,y=10)
window.mainloop()

Tkinter Text Widget Save to File

So, I'm quite new to using python and I wanted to learn more about it so I decided to download a sticky note program from the internet (Rhinote) and study / modify it to use a menu bar instead of control commands to execute the methods. I also modified it to work with Python 3.x instead of Python 2.
The problem I'm coming up with after modifying it with the menu bar is that it creates the file but doesn't actually write to it. I've been trying to fix this for a while now so any help is appreciated.
Here is the code I have currently:
from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system
# the root window:
def Sticky():
r = Tk()
r.option_add('*font', '{Helvetica} 11')
t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
t.focus_set()
t.pack(fill = 'both', expand = 1)
r.geometry('220x235')
r.title('Note')
text = TextWidget()
m = tkinter.Menu(r)
m.add_command(label="+", command=text.new_window)
m.add_command(label="Save", command=text.save_file)
m.add_command(label="Save As", command=text.save_file_as)
m.add_command(label="Open", command=text.open_file)
r.config(menu=m)
r.mainloop()
# the text widget, and all of its functions:
class TextWidget(Text):
def __init__(self):
Text.__init__(self)
self.filename = ''
self._filetypes = [
('Text', '*.txt'),
('All files', '*'),
]
def save_file(self, whatever = None):
if (self.filename == ''):
self.save_file_as()
else:
f = open(self.filename, 'w')
f.write(self.get('1.0', 'end'))
f.close()
tkinter.messagebox.showinfo('FYI', 'File Saved.')
def save_file_as(self, whatever = None):
self.filename = tkinter.filedialog.asksaveasfilename(defaultextension='.txt',
filetypes = self._filetypes)
f = open(self.filename, 'w')
f.write(self.get('1.0', 'end'))
f.close()
tkinter.messagebox.showinfo('FYI', 'File Saved')
def open_file(self, whatever = None, filename = None):
if not filename:
self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
else:
self.filename = filename
if not (self.filename == ''):
f = open(self.filename, 'r')
f2 = f.read()
self.delete('1.0', 'end')
self.insert('1.0', f2)
f.close()
self.title('Sticky %s)' % self.filename)
def new_window(self):
Sticky()
def help(whatever = None):
tkinter.messagebox.showinfo('Help', message = '''
Help
''')
# make it so:
if __name__ == '__main__':
Sticky()
And here is the Rhinote program I'm trying to modify:
from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system
# the root window:
def Rhinote():
r = Tk()
r.option_add('*font', '{Helvetica} 11')
t = TextWidget(r, bg = '#f9f3a9', wrap = 'word', undo = True)
t.focus_set()
t.pack(fill = 'both', expand = 1)
r.geometry('220x235')
r.title('Rhinote')
r.mainloop()
# the text widget, and all of its functions:
class TextWidget(Text):
def save_file(self, whatever = None):
if (self.filename == ''):
self.save_file_as()
self.master.title('Rhinote %s' % self.filename)
else:
f = open(self.filename, 'w')
f.write(self.get('1.0', 'end'))
f.close()
self.master.title('Rhinote %s' % self.filename)
tkinter.messageb ox.showinfo('FYI', 'File Saved.')
def save_file_as(self, whatever = None):
self.filename = tkinter.filedialog.asksaveasfilename(filetypes = self._filetypes)
f = open(self.filename, 'w')
f.write(self.get('1.0', 'end'))
f.close()
tkinter.messagebox.showinfo('FYI', 'File Saved')
def open_file(self, whatever = None, filename = None):
if not filename:
self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
self.master.title('Rhinote %s' % self.filename)
else:
self.filename = filename
self.master.title('Rhinote %s' % self.filename)
if not (self.filename == ''):
f = open(self.filename, 'r')
f2 = f.read()
self.delete('1.0', 'end')
self.insert('1.0', f2)
f.close()
self.master.title('Rhinote %s)' % self.filename)
def new_window(self, event):
Rhinote()
def printfile(self, whatever = None):
f = open(self.printfilename, 'w')
f.write(self.get('1.0', 'end'))
f.close
# 'enscript' formats the text; lpr sends it to the default printer;
# enscript's -B option suppresses page headers.
system('enscript -B --word-wrap $HOME/.Rhinoteprintfile > lpr &')
def help(self, whatever = None):
tkinter.messagebox.showinfo('Rhinote Help', message = '''
Editing Commands
Ctrl-x : Cut selected text
Ctrl-c : Copy selected text
Ctrl-v : Paste cut/copied text
Ctrl-Z : Undo
Ctrl-Shift-z : Redo
File Commands
Ctrl-o : Open file
Ctrl-s : Save current note
Ctrl-a : Save current note as <filename>
Ctrl-p : Print current note
Ctrl-n : Open new Rhinote
General
Ctrl-h : Display this help window
Rhinote version 0.7.4
Free Software distributed under the GNU General Public License
http://rhinote.tuxfamily.org
''')
def __init__(self, master, **kw):
Text.__init__(self, master, **kw)
self.bind('<Control-n>', self.new_window)
self.bind('<Control-N>', self.new_window)
self.bind('<Control-o>', self.open_file)
self.bind('<Control-O>', self.open_file)
self.bind('<Control-s>', self.save_file)
self.bind('<Control-S>', self.save_file)
self.bind('<Control-a>', self.save_file_as)
self.bind('<Control-A>', self.save_file_as)
self.bind('<Control-p>', self.printfile)
self.bind('<Control-P>', self.printfile)
self.bind('<Control-h>', self.help)
self.bind('<Control-H>', self.help)
self.master = master
self.filename = ''
self.printfilename = os.environ['HOME']+'/.Rhinoteprintfile'
self._filetypes = [
('Text/ASCII', '*.txt'),
('Rhinote files', '*.rhi'),
('All files', '*'),
]
# make it so:
if __name__ == '__main__':
Rhinote()
It was nice that you changed to using menu, but there is one thing you forgot, the Text that's showing onscreen isn't the one named text, it was this while you're retrieving the data from text which is empty because it's covered by t and it wasn't even packed:
t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
t.focus_set()
t.pack(fill = 'both', expand = 1)
Since you used focus_set on it which will be above all other widgets. Just to say simple, you can change your program to something like this, which you wouldn't even need the text.
from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system
# the root window:
def Sticky():
r = Tk()
r.option_add('*font', '{Helvetica} 11')
t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
t.focus_set()
t.pack(fill = 'both', expand = 1)
r.geometry('220x235')
r.title('Note')
TextWidget(t) # pass along t, your Text
m = tkinter.Menu(r)
m.add_command(label="+", command=text.new_window)
m.add_command(label="Save", command=text.save_file)
m.add_command(label="Save As", command=text.save_file_as)
m.add_command(label="Open", command=text.open_file)
r.config(menu=m)
r.mainloop()
# the text widget, and all of its functions:
class TextWidget:
def __init__(self, text):
self.text = text # pass the text widget
self.filename = ''
self._filetypes = [
('Text', '*.txt'),
('All files', '*'),
]
def save_file(self, whatever = None):
if (self.filename == ''):
self.save_file_as()
else:
f = open(self.filename, 'w')
f.write(self.text.get('1.0', 'end')) # change every 'self' that refers to the Text, to self.text
f.close()
tkinter.messagebox.showinfo('FYI', 'File Saved.')
def save_file_as(self, whatever = None):
self.filename = tkinter.filedialog.asksaveasfilename(defaultextension='.txt',
filetypes = self._filetypes)
f = open(self.filename, 'w')
f.write(self.text.get('1.0', 'end'))
f.close()
tkinter.messagebox.showinfo('FYI', 'File Saved')
def open_file(self, whatever = None, filename = None):
if not filename:
self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
else:
self.filename = filename
if not (self.filename == ''):
f = open(self.filename, 'r')
f2 = f.read()
self.text.delete('1.0', 'end')
self.text.insert('1.0', f2)
f.close()
self.text.title('Sticky %s)' % self.filename)
def new_window(self):
Sticky()
def help(whatever = None):
tkinter.messagebox.showinfo('Help', message = '''
Help
''')
# make it so:
if __name__ == '__main__':
Sticky()
Since TextWidget is a Text subclass, you should just use it wherever the original program uses the latter. To make that possible, it needs to properly initialize its super class.
Fortunately, not much needs to be changed to do that and use it correctly.
Below are portions of your code that need to be changed:
from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system
# the root window:
def Sticky():
r = Tk()
r.option_add('*font', '{Helvetica} 11')
text = TextWidget(r, bg='#f9f3a9', wrap='word', undo=True) # create subclass here (and
# call it text instead of t)
text.focus_set()
text.pack(fill='both', expand=1)
r.geometry('220x235')
r.title('Note')
m = tkinter.Menu(r)
m.add_command(label="+", command=text.new_window)
m.add_command(label="Save", command=text.save_file)
m.add_command(label="Save As", command=text.save_file_as)
m.add_command(label="Open", command=text.open_file)
r.config(menu=m)
r.mainloop()
# the text widget, and all of its functions:
class TextWidget(Text):
def __init__(self, *args, **kwargs):
Text.__init__(self, *args, **kwargs) # pass all args to superclass
self.filename = ''
self._filetypes = [
('Text', '*.txt'),
('All files', '*'),
]
def save_file(self, whatever=None):
REST OF YOUR CODE, UNCHANGED, GOES HERE...

Categories

Resources