I'm trying get a list of .xlsm files from a folder, and generate a scrollable canvas from which the tabs needed for import can be selected manually using the check buttons (all having the same tab format e.g. tab1, tab2, tab3, tab4).
The major issue I'm having is getting weights to work correctly for the headers in relation to their canvas columns, as longer file names distorts the weight.
I've tried playing with the weights and can't seem to figure out a workaround. I also attempted using treeview as an alternative but this seems to introduce far bigger issues with using checkbuttons. Would it possible to freeze the top row if the headers were placed inside the canvas itself, or could I implement something like a bind so that the header frames individual columns align with the width of the columns of the canvas frame?
import os
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
class MainFrame:
def __init__(self, master):
master.geometry('1000x200')
self.master_tab = ttk.Notebook(master)
self.master_tab.grid(row=0, column=0, sticky='nsew')
# Sub-Classes
self.file_select = FileSelect(self.master_tab, main=self)
class FileSelect:
def __init__(self, master, main):
self.main = main
# ================== Primary Frame ==================
self.primary_frame = tk.Frame(master)
self.primary_frame.grid(row=0, column=0, sticky='NSEW')
master.add(self.primary_frame, text='Import Selection')
self.primary_frame.columnconfigure(0, weight=1)
self.primary_frame.rowconfigure(1, weight=1)
# ================== File Selection Frame ==================
self.selection_frame = tk.Frame(self.primary_frame)
self.selection_frame.grid(row=0, column=0, sticky='EW')
# Button - Select Directory
self.fp_button = tk.Button(self.selection_frame, text='Open:', command=self.directory_path)
self.fp_button.grid(row=0, column=0, sticky='W')
# Label - Display Directory
self.fp_text = tk.StringVar(value='Select Import Directory')
self.fp_label = tk.Label(self.selection_frame, textvariable=self.fp_text, anchor='w')
self.fp_label.grid(row=0, column=1, sticky='W')
# ================== Canvas Frame ==================
self.canvas_frame = tk.Frame(self.primary_frame)
self.canvas_frame.grid(row=1, column=0, sticky='NSEW')
self.canvas_frame.rowconfigure(1, weight=1)
# Canvas Header Labels
for header_name, x in zip(['File Name', 'Tab 1', 'Tab 2', 'Tab 3', 'Tab 4'], range(5)):
tk.Label(self.canvas_frame, text=header_name, anchor='w').grid(row=0, column=x, sticky='EW')
self.canvas_frame.columnconfigure(x, weight=1)
# Scroll Canvas
self.canvas = tk.Canvas(self.canvas_frame, bg='#BDCDFF')
self.canvas.grid(row=1, column=0, columnspan=5, sticky='NSEW')
self.canvas.bind('<Configure>', self.frame_width)
# Scrollbar
self.scroll_y = tk.Scrollbar(self.canvas_frame, orient="vertical", command=self.canvas.yview)
self.scroll_y.grid(row=1, column=5, sticky='NS')
# Canvas Sub-Frame
self.canvas_sub_frame = tk.Frame(self.canvas)
for x in range(5):
self.canvas_sub_frame.columnconfigure(x, weight=1)
self.canvas_frame_window = self.canvas.create_window(0, 0, anchor='nw', window=self.canvas_sub_frame)
self.canvas_sub_frame.bind('<Configure>', self.config_frame)
def config_frame(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox('all'), yscrollcommand=self.scroll_y.set)
def frame_width(self, event):
canvas_width = event.width
event.widget.itemconfigure(self.canvas_frame_window, width=canvas_width)
def directory_path(self):
try:
# Select file path
directory = filedialog.askdirectory(initialdir='/', title='Select a directory')
self.fp_text.set(str(directory))
os.chdir(directory)
# Updates GUI with .xlsm file list & checkboxes
if len(os.listdir(directory)) != 0:
y = -1
for tb in os.listdir(directory):
if not tb.endswith('.xlsm'):
print(str(tb) + ' does not have ;.xlsm file extension')
else:
y += 1
file_name = tk.Label(self.canvas_sub_frame, text=tb, anchor='w', bg='#96ADF3')
file_name.grid(row=y, column=0, sticky='EW')
for x in range(4):
tb_period = tk.Checkbutton(self.canvas_sub_frame, anchor='w', bg='#C2D0F9')
tb_period.grid(row=y, column=x+1, sticky='EW')
else:
print('No files in directory')
# Filepath error handling exception
except os.error:
print('OS ERROR')
if __name__ == '__main__':
root = tk.Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
MainFrame(root)
root.mainloop()
The simplest solution is to use two canvases, and then set up a binding so that whenever the size of the inner frame changes, you update the headers to match the columns.
It might look something like this:
def config_frame(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox('all'), yscrollcommand=self.scroll_y.set)
self.canvas.after_idle(self.reset_headers)
def reset_headers(self):
for column in range(self.canvas_sub_frame.grid_size()[0]):
bbox = self.canvas_sub_frame.grid_bbox(column, 0)
self.canvas_frame.columnconfigure(column, minsize = bbox[2])
I am creating an EXIF viewer using Tkinter. I need to load an image, which I am already doing, but I can't position it on top of my window into a frame. I used
top_frame = Frame(root)
top_frame.pack(side=TOP)
But I don't know how to position the picture I'm loading into it.
Everytime I load an image it adds it to the view, I'd like to delete the precedent one and add the new one. And this picture must be always inside a precise frame, independently on its size.
This is how I'm visualizing it now:
This is my code:
from tkinter import *
import PIL
from PIL import ImageTk, Image
from tkinter import filedialog
import tkinter as tk
from PIL.ExifTags import TAGS
from exifread.tags import exif
root = tk.Tk()
root.title('Exif Viewer')
root.geometry('500x550')
root.iconbitmap("../icons/exif.png")
def browse_image():
global image_object, image_loaded_label
image_loaded_label = None
root.filename = filedialog.askopenfilename(initialdir="/", title="Select An Image",
filetypes=(("jpeg files", "*.jpeg"), ("png files", "*.png")))
image_object = Image.open(root.filename)
image_loaded = ImageTk.PhotoImage(image_object)
image_loaded_label = Label(image=image_loaded)
image_loaded_label.pack()
image_loaded_label.image = image_loaded
def rotate_image(direction):
global image_object
angle = {"left":90, "right":-90}[direction]
image_object = image_object.rotate(angle)
rotated_tk = ImageTk.PhotoImage(image_object)
image_loaded_label.config(image=rotated_tk)
image_loaded_label.image = rotated_tk #Prevent garbage collection
def get_exif():
global image_object
exif_data = image_object._getexif()
for tag_id in exif_data:
tag_name = TAGS.get(tag_id, tag_id)
value = exif_data.get(tag_id)
print(f"{tag_name:25}: {value}")
top_frame = Frame(root)
top_frame.pack(side=TOP)
bottom_frame = Frame(root)
bottom_frame.pack(side=BOTTOM)
browse_button = Button(bottom_frame, padx=20, pady=5, text="Load image", command=browse_image)
browse_button.grid(row=1, column=0)
browse_button.pack()
rotate_left_button = Button(bottom_frame, padx=10, pady=5, text="Rotate left", command=lambda: rotate_image("left"))
rotate_left_button.pack(side=LEFT)
rotate_right_button = Button(bottom_frame, padx=10, pady=5, text="Rotate right", command=lambda: rotate_image("right"))
rotate_right_button.pack(side=RIGHT)
get_exif = Button(bottom_frame, padx=20, pady=5, text="Get EXIF", command=get_exif)
get_exif.pack(side=TOP)
exit_button = Button(bottom_frame, padx=20, pady=5, text="Exit", command=root.quit)
exit_button.pack()
root.mainloop()
I'm new to python and I'm wondering how to validate if label text exists. I'm getting an error:
Below's my full code. You can see the function validate at the bottom, and I'm figuring out how to make the label work in if else condition.
import openpyxl, os
import glob
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
class Root(Tk):
def __init__(self):
super(Root, self).__init__()
#Add a widget title
self.title("Automated filling up of form in iPage")
#Set widget width and height
self.minsize(300, 200)
#Display browse button
self.displayForm()
def doubleQuote(self, word):
return '"%s"' % word
def displayForm(self):
#Display label frame
self.labelFrame = ttk.LabelFrame(self, text = "Open Excel File")
self.labelFrame.grid(column=1, row=2, pady=5, sticky=NW)
#Create browse button
self.button = ttk.Button(self.labelFrame, text = "Browse a File",command = self.openFileDialog)
self.button.grid(column=1, row=1, padx=5, pady=5)
ttk.Label(self, text="Cell From:").grid(column=0, row=0, padx=5)
ttk.Label(self, text="Cell To:").grid(column=0, row=1, padx=5)
self.cf = StringVar()
self.ct = StringVar()
self.cellFrom = ttk.Entry(self, textvariable=self.cf)
self.cellTo = ttk.Entry(self, textvariable=self.ct)
self.cellFrom.grid(column=1, row=0, pady=5)
self.cellTo.grid(column=1, row=1, pady=5)
self.cf.trace("w",self.validate)
self.ct.trace("w",self.validate)
self.submitBtn = ttk.Button(self, text='Submit', command=self.validate)
self.submitBtn.grid(column=1, row=3, pady=5, sticky=NW)
def openFileDialog(self):
#Create a file dialog
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select A File", filetype =
[("Excel files", ".xlsx .xls")])
self.label = ttk.Label(self.labelFrame, text = "", textvariable=self.fl)
self.label.grid(column = 1, row = 2)
#Change label text to file directory
self.label.configure(text = self.filename)
self.label.trace("w",self.validate)
#Return tail of the path
self.trimmed = os.path.basename(self.filename)
#Pass tail variable
self.openSpreadsheet(self.trimmed)
def openSpreadsheet(self, tail):
#Open excel spreadsheet
self.wb = openpyxl.load_workbook(tail)
self.sheet = self.wb['Sheet1']
#Return data from excel spreadsheet
for rowOfCellObjects in self.sheet[self.cf.get():self.ct.get()]:
#Loop through data
for link in rowOfCellObjects:
#Remove www and firstlightplus.com text
self.cleanURL = link.value.replace("www.", " ").replace(".firstlightplus.com", "")
print(self.cleanURL)
def validate(self, *args):
#Retrieve the value from the entry and store it to a variable
if self.cf.get() and self.ct.get() and self.label["text"]:
print("normal")
self.submitBtn.config(state='normal')
else:
print("disabled")
self.submitBtn.config(state='disabled')
root = Root()
root.mainloop()
I believe the problem is the validate function can be called before the openFileDialog function. This way, the label attribute is being accessed before it has been created.
A simple solution would be initialize the attribute in the displayForm function:
def displayForm(self):
#Display label frame
self.labelFrame = ttk.LabelFrame(self, text = "Open Excel File")
self.labelFrame.grid(column=1, row=2, pady=5, sticky=NW)
self.label = None
# ... Rest of the code
And then, before accessing the attribute, test if it exists:
def validate(self, *args):
#Retrieve the value from the entry and store it to a variable
if self.cf.get() and self.ct.get() and self.label and self.label["text"]:
print("normal")
self.submitBtn.config(state='normal')
else:
print("disabled")
self.submitBtn.config(state='disabled')
Introduction: My Python Tkinter application is designed to have a scrollbar on the side so that if the window is resized, the application can still be viewed via the scrollbar. I do this by putting a frame with all my content inside a canvas, with a scrollbar controlling the canvas. On window resize, I have a function called resizeCanvas which resizes the canvas.
Problem: After I resize the window, the scrollbar sort of works but it seems to jump around and fidget like its having a seizure. However, at initialization the scroll bar works smoothly. So resizing the window seems to be the problem. Any suggestions on why the scroll bar is behaving like this?
Application Hierarchy:
Tkinter root
frame (just a container for the canvas)
canvas (scroll bar is attached to this canvas)
frame (content is in this frame)
NOTE: Python 2.7.2
Code Snippit:
myframe=Frame(root,width=winx,height=winy)
myframe.place(x=0,y=0)
canvas = Tkinter.Canvas(myframe,width=winx,height=winy)
frame = Frame(canvas,width=winx,height=winy)
myscrollbar=Scrollbar(myframe,orient="vertical")
myscrollbar.configure(command=canvas.yview)
canvas.configure(yscrollcommand=myscrollbar.set)
myscrollbar.pack(side="left",fill="y")
canvas.pack(side="left")
canvas.create_window((0,0),window=frame,anchor='nw')
frame.bind("<Configure>", initializeCanvas)
bind("<Configure>", resizeCanvas)
def initializeCanvas(self, event):
canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
canvas.config(width=cwidth, height=cheight)
Entire Code:
import sys
#external python files are in the includes folder
sys.path.insert(0, 'includes')
import webbrowser
import os
import Tkinter
import tkFileDialog
import tkMessageBox
import ConfigParser
from ttk import *
import tkFont
import Tix
# configurations held in this variable
config = ConfigParser.RawConfigParser()
# pady padding for create buttons
py = 15
# padx padding for create buttons
px = 5
# padding on left side for indenting elements
indentx = 25
winx = 815
winy = 515
# array to hold features
FEATURES =['']
# wrapper class for GUI
class AppTk(Tkinter.Tk):
def __init__(self, parent):
Tkinter.Tk.__init__(self, parent)
self.parent = parent
self.settings = "./settings/settings.cfg"
self.initialize_gui()
self.minsize(winx, 100)
sizex = winx
sizey = winy
posx = 100
posy = 100
self.wm_geometry("%dx%d+%d+%d" % (sizex, sizey, posx, posy))
try:
self.iconbitmap('./imgs/favicon.ico')
except Exception, e:
print "\n****Error occurred (GUI_MBD_File_Creator.init): favicon not found!"
# Setup grid of elements in GUI
# action: on start of application
def initialize_gui(self):
# ----------------------------------------------------
# START Settings frame initialization
# ----------------------------------------------------
self.myframe=Frame(self,width=winx,height=winy)
self.myframe.place(x=0,y=0)
self.canvas = Tkinter.Canvas(self.myframe,width=winx,height=winy)
self.frame = Frame(self.canvas,width=winx,height=winy)
self.myscrollbar=Scrollbar(self.myframe,orient="vertical")
self.myscrollbar.configure(command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.myscrollbar.set)
self.myscrollbar.pack(side="left",fill="y")
self.canvas.pack(side="left")
self.canvas.create_window((0,0),window=self.frame,anchor='nw')
self.frame.bind("<Configure>",self.initializeCanvas)
self.bind("<Configure>",self.resizeCanvas)
frameFont = tkFont.Font(size=13, weight=tkFont.BOLD)
self.frameSettings = Tkinter.LabelFrame(self.frame, text="Settings: fill these out first", relief="groove", borderwidth="3", font=frameFont)
self.frameSettings.grid(sticky="EW", padx=px, pady=(5,15))
labelSpreadsheet = Label(self.frameSettings, text="1. Spreadsheet Path:")
labelSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableSpreadsheet = Tkinter.StringVar()
self.entrySpreadsheet = Entry(self.frameSettings, textvariable=variableSpreadsheet, width=90, state=Tkinter.DISABLED)
self.entrySpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entrySpreadsheet.svar = variableSpreadsheet
buttonSpreadsheet = Button(self.frameSettings, text="Browse...")
buttonSpreadsheet.grid(row=0, column=2, sticky='W', padx=(0,10))
labelPath = Label(self.frameSettings, text="2. Root Save Path:")
labelPath.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variablePath = Tkinter.StringVar()
self.entryPath = Entry(self.frameSettings, textvariable=variablePath, width=90, state=Tkinter.DISABLED)
self.entryPath.grid(row=1, column=1, sticky='W', padx=px, pady=(5,10))
self.entryPath.svar = variablePath
buttonPath = Button(self.frameSettings, text="Browse...")
buttonPath.grid(row=1, column=2, sticky='W', padx=(0,10), pady=(0,5))
# ----------------------------------------------------
# START Creation Menu frame initialization
# ----------------------------------------------------
self.frameCreationIndividual = Tkinter.LabelFrame(self.frame, text="Feature Files Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationIndividual.grid(sticky="EW", padx=px, pady=(5,15))
labelReq = Label(self.frameCreationIndividual, text="3. Feature(s):")
labelReq.grid(row=0, column=0, sticky='NW', pady=(5,0), padx=(indentx,15))
self.scrollbarReq = Scrollbar(self.frameCreationIndividual)
self.scrollbarReq.grid(row=1, column=3, rowspan=16, sticky="NSW", pady=(0,15),padx=(0,20))
variableSelectAll = Tkinter.IntVar()
self.checkSelectAll = Checkbutton(self.frameCreationIndividual, text = "Select All", variable = variableSelectAll, onvalue = 1, offvalue = 0)
self.checkSelectAll.grid(row=0, column=1, columnspan=2, sticky='NE', padx=px, pady=(5,0))
self.checkSelectAll.svar = variableSelectAll
labelReq = Label(self.frameCreationIndividual, text="4. Files:")
labelReq.grid(row=0, column=5, sticky='NW', pady=(5,0), padx=15)
variableIndividualFFS = Tkinter.IntVar()
self.checkIndividualFFS = Checkbutton(self.frameCreationIndividual, text = "Create Feature File", variable = variableIndividualFFS, onvalue = 1, offvalue = 0)
self.checkIndividualFFS.grid(row=1, column=5, sticky='NW', padx=15)
self.checkIndividualFFS.svar = variableIndividualFFS
variableIndividualSFS = Tkinter.IntVar()
self.checkIndividualSFS = Checkbutton(self.frameCreationIndividual, text = "Create SubFeature Files", variable = variableIndividualSFS, onvalue = 1, offvalue = 0)
self.checkIndividualSFS.grid(row=2, column=5, sticky='NW', padx=15)
self.checkIndividualSFS.svar = variableIndividualSFS
variableIndividualDO = Tkinter.IntVar()
self.checkIndividualDO = Checkbutton(self.frameCreationIndividual, text = "Create Doc Outline", variable = variableIndividualDO, onvalue = 1, offvalue = 0)
self.checkIndividualDO.grid(row=3, column=5, sticky='NW', padx=15)
self.checkIndividualDO.svar = variableIndividualDO
variableIndividualDWR = Tkinter.IntVar()
self.checkIndividualDWR = Checkbutton(self.frameCreationIndividual, text = "Create Doc With Requirements", variable = variableIndividualDWR, onvalue = 1, offvalue = 0)
self.checkIndividualDWR.grid(row=4, column=5, sticky='NW', padx=(15,30))
self.checkIndividualDWR.svar = variableIndividualDWR
self.buttonIndividualAll = Button(self.frameCreationIndividual, text="Create...", width=43)
self.buttonIndividualAll.grid(row=1, column=6, rowspan=4, sticky='NESW', padx=px)
# ----------------------------------------------------
# START Entire System Creation frame initialization
# ----------------------------------------------------
self.frameCreationSystem = Tkinter.LabelFrame(self.frame, text="System Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationSystem.grid(sticky="EW", padx=px, pady=15)
self.buttonLAIF = Button(self.frameCreationSystem, text="Create Layers/App Integration Files", width=35)
self.buttonLAIF.grid(row=11, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(16,8))
self.buttonDO = Button(self.frameCreationSystem, text="Create Entire Doc Outline")
self.buttonDO.grid(row=12, column=0, sticky='NESW', ipady=5, padx=(indentx,0), pady=(8,10))
# ----------------------------------------------------
# START Feature Tab Creation Frame initialization
# ----------------------------------------------------
self.frameCreationNew = Tkinter.LabelFrame(self.frame, text="Feature Tab Creation Menu", relief="groove", borderwidth="3", font=frameFont)
self.frameCreationNew.grid(sticky="EW", padx=px, pady=(15,5))
labelIssueSpreadsheet = Label(self.frameCreationNew, text="2. Feature Spreadsheet Path:")
labelIssueSpreadsheet.grid(row=0, column=0, sticky='W', padx=(indentx,0))
variableIssueSpreadsheet = Tkinter.StringVar()
self.entryIssueSpreadsheet = Entry(self.frameCreationNew, textvariable=variableIssueSpreadsheet, width=83, state=Tkinter.DISABLED)
self.entryIssueSpreadsheet.grid(row=0, column=1, sticky='W', padx=px, pady=5)
self.entryIssueSpreadsheet.svar = variableIssueSpreadsheet
buttonIssueSpreadsheet = Button(self.frameCreationNew, text="Browse...")
buttonIssueSpreadsheet.grid(row=0, column=2, sticky='W')
labelFeatureTab = Label(self.frameCreationNew, text="3. Feature Name:")
labelFeatureTab.grid(row=1, column=0, sticky='W', padx=(indentx,0))
variableFeatureTab = Tkinter.StringVar()
self.entryFeatureTab = Entry(self.frameCreationNew, textvariable=variableFeatureTab, width=83)
self.entryFeatureTab.grid(row=1, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureTab.svar = variableFeatureTab
labelFeatureAbbrv = Label(self.frameCreationNew, text="4. Feature Abbreviation:")
labelFeatureAbbrv.grid(row=2, column=0, sticky='W', padx=(indentx,0))
variableFeatureAbbrv = Tkinter.StringVar()
self.entryFeatureAbbrv = Entry(self.frameCreationNew, textvariable=variableFeatureAbbrv, width=83)
self.entryFeatureAbbrv.grid(row=2, column=1, sticky='W', padx=px, pady=5)
self.entryFeatureAbbrv.svar = variableFeatureAbbrv
self.buttonNewFeature = Button(self.frameCreationNew, text="Create Feature Tab", width=35)
self.buttonNewFeature.grid(row=3, column=0, columnspan =2, sticky='NWS', ipady=5, pady=(8,10), padx=(indentx,0))
# ----------------------------------------------------
# START general purpose methods
# ----------------------------------------------------
def initializeCanvas(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=winx,height=winy)
def resizeCanvas(self, event):
self.update()
cwidth = self.winfo_width()
cheight = self.winfo_height()
self.canvas.config(scrollregion=self.canvas.bbox("all"), width=cwidth, height=cheight)
# ----------------------------------------------------
# Initialize application
# ----------------------------------------------------
if __name__ == "__main__":
app = AppTk(None)
app.title("MBD File Creator")
app.mainloop()
While there may be other errors, you have one very critical flaw: you are creating a binding for the <Configure> event to self. Because self is the instance of the root window, every widget you create inherits this binding. Your resizeCanvas method is literally being called hundreds of times at startup, and hundreds of times when the window is resized.
You also have the problem where you are calling update in an event handler. As a general rule, this is bad. In effect, it's like calling mainloop in that it will not return until all events are processed. If your code causes more events to be processed (such as reconfiguring a window and causing the <configure> event to fire, you end up in a recursive loop.
You probably need to remove the calls to self.update() and/or replace them with the less dangerous self.update_idletasks(). You also need to either remove the <Configure> binding on self, or in the method you need to check for which widget caused the event to fire (ie: check that the event.widget is the root window).
Try first to save the canvas.create_window to a variable as following:
self.windows_item = canvas.create_window((0,0),window=frame,anchor='nw')
then at the end of resizeCanvas to call the following method:
def update(self):
"Update the canvas and the scrollregion"
self.update_idletasks()
canvas.config(scrollregion=canvas.bbox(self.windows_item))
Hope it helps!
Most of it found here: https://stackoverflow.com/a/47985165/2160507
I've no idea why I haven't been able to find a good solution to this problem yet, it seems very elementary to me .. though not elementary enough to figure it out satisfactorily.
A chapter project in a cryptology book Im reading instructs to write a simple mono-alphabetic cipher in your preferred language ... I chose Python.
It starts with a simple tkinter app. with some widgets, lol ... duh. Anyways here's the relevant code:
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
class Application(Frame):
def __init__(self, master):
""" Initialize Frame. """
super(Application, self).__init__(master)
self.grid()
self.create_widgets()
def create_widgets(self):
""" Set all program widgets. """
# set all labels
Label(self, text = "Plaintext File: ")\
.grid(row=0, column=0, sticky=W)
Label(self, text = "Ciphertext: ")\
.grid(row=3, column=0, sticky=W)
Label(self, text = "Offset: ")\
.grid(row=2, column=0, sticky=W)
# set buttons
Button(self, text = "Browse", command=self.load_file, width=10)\
.grid(row=1, column=0, sticky=W)
# set entry field
self.file_name = Text(self, width=39, height=1, wrap=WORD)
self.file_name.grid(row=1, column=1, columnspan=4, sticky=W)
# set display field
self.output_display = Text(self, width=50, height=5, wrap=WORD)
self.output_display.grid(row=4, column=0, columnspan=4, sticky=W)
# set offset amount spinbox
self.offset_amt = IntVar()
self.offset_amt = Spinbox(self, from_=1, to=13)
self.offset_amt.grid(row=2, column=1, sticky=W)
# set shift direction
self.shift_dir = StringVar()
self.shift_dir.set('r')
Radiobutton(self, text="Shift Right", variable=self.shift_dir, value='r')\
.grid(row=2, column=2, sticky=W)
Radiobutton(self, text="Shift Left", variable=self.shift_dir, value='l')\
.grid(row=2, column=3, sticky=W)
def load_file(self):
self.filename = askopenfilename(initialdir='~')
if self.filename:
try:
#self.settings.set(self.filename)
self.file_name.delete(0.0, END)
self.file_name.insert(0.0, open(self.filename, 'r'))
except IOError:
showerror("Open Source File", "Failed to read file \n'%s'"%self.filename)
return
def main():
root = Tk()
root.title("simple mono-alpha encrypter")
root.geometry('450x250')
app = Application(root)
for child in app.winfo_children():
child.grid_configure(padx=3, pady=3)
root.mainloop()
main()
There's only a very little of it that actually does anything besides create widgets right now, I decided to post it all since its not that involved yet and someone can get a good idea of where Im at.
My problem that I haven't solved is that when I press use the 'Browse' button to choose a file to encrypt and then choose the file, the file content is displayed in the 'file_name' text widget, rather than the file name itself.
Im thinking that I have to change the 'filename' variable to not the actual file name but the file instead and then load the content of the File Name field from the open file dialog box in a 'filename' variable. I just haven't been able to figure out how to do that yet.
Nor have I come across an appropriate method to do it.
Any guidance??
Thanks
F
Displaying the Filename
self.file_name.insert(0.0, self.filename)
Displaying the File Contents
You just need to read the data in from the file. See http://docs.python.org/library/stdtypes.html#file-objects
with open(self.filename, 'r') as inp_file:
self.file_name.insert(0.0, inp_file.read())