ive been working on a duplicate image detector for a bit now, and ive run into an error that is only encountered for me, as ive seen nobody else have this error when they test it. the error is in the function showImages() where i have 3 labels that i want to use, yet only those three labels dont work. the buttons and the images work just fine, but the labels do not. i have been pulling my hair out for the past couple days trying to find what is making these 3 labels not pop up.
the code should would fine on other computers, granted you have the modules. to test, you need 2 folders with images, and some of those images should have a duplicate in its counterpart folder.
from tkinter import filedialog
import cv2, numpy, os, math
from tkinter import *
from PIL import Image, ImageTk
import tkinter as tk
root = Tk()
root.configure(background="black")
canvas = Canvas(root, bd=0, bg = 'black', width = 1920, height = 1080)
canvas.pack()
canvas.configure(bg = 'black')
file1 = ''
file2 = ''
identicalImages1 = []
identicalImages2 = []
directories = []
blacklisted = [".gif" ,".avi",".exe", ".wav", ".avf", ".mov", ".mp4", ".webm", ".flv", ".txt", ".swf", ".log", ".url"]
fonta = 'Terminal'
text_color = 'lime'
indecs = 0
leniancy = 4 #default
label1 = Label(root, bg = 'black', fg = text_color, text= '', font = (fonta, 30)) # 5 given labels
label2 = Label(root, bg = 'black', fg = text_color, text= '', font = (fonta, 30))
label3 = Label(root, bg = 'black', fg = text_color, text= '', font = (fonta, 30))
label4 = Label(root, bg = 'black', fg = text_color, text= '', font = (fonta, 30))
label5 = Label(root, bg = 'black', fg = text_color, text= '', font = (fonta, 30))
image1 = Label(root, bg = 'black', fg = text_color, font = (fonta, 30)) # 5 given images
image2 = Label(root, bg = 'black', fg = text_color, font = (fonta, 30))
image3 = Label(root, bg = 'black', fg = text_color, font = (fonta, 30))
image4 = Label(root, bg = 'black', fg = text_color, font = (fonta, 30))
image5 = Label(root, bg = 'black', fg = text_color, font = (fonta, 30))
button1 = Button(root, bg = 'black', fg = text_color, font = (fonta, 30)) # 5 given buttons
button2 = Button(root, bg = 'black', fg = text_color, font = (fonta, 30))
button3 = Button(root, bg = 'black', fg = text_color, font = (fonta, 30))
button4 = Button(root, bg = 'black', fg = text_color, font = (fonta, 30))
button5 = Button(root, bg = 'black', fg = text_color, font = (fonta, 30))
slider1 = Scale(root,bg = 'black', fg = text_color)
slider2 = Scale(root,bg = 'black', fg = text_color)
def forgor(): # resets every widget when swapping pages
try:
label1.place_forget()
label1.config(font = (fonta, 30))
label2.place_forget()
label2.config(font = (fonta, 30))
label3.place_forget()
label3.config(font = (fonta, 30))
label4.place_forget()
label4.config(font = (fonta, 30))
label5.place_forget()
label5.config(font = (fonta, 30))
button1.place_forget()
button1.config(font = (fonta, 30))
button2.place_forget()
button2.config(font = (fonta, 30))
button3.place_forget()
button3.config(font = (fonta, 30))
button4.place_forget()
button4.config(font = (fonta, 30))
button5.place_forget()
button5.config(font = (fonta, 30))
image1.place_forget()
image2.place_forget()
image3.place_forget()
image4.place_forget()
image5.place_forget()
slider1.place_forget()
slider1.place_forget()
except:
pass
def start1(): # main menu
global file1, file2
file1 = ''
file2 = ''
forgor()
label1.config(bd = 2, text = "IMAGE DUPE COMPARER")
label1.place(x = 960, y = 50, anchor= 'center') # title name
label2.config(bd = 2)
label2.place(x = 480, y = 530, anchor= 'center') # folder 1 name
label3.config(bd = 2)
label3.place(x = 1440, y = 530, anchor= 'center') # folder 2 name
button1.config(text = "folder 1", command = lambda: ask_for_folder(1)) # folder 1 button
button1.place(x = 480, y = 590, anchor= 'center')
button2.config(text = "folder 2", command = lambda: ask_for_folder(2)) # folder 2 button
button2.place(x = 1440, y = 590, anchor= 'center')
button3.config(text = "Go!", command = start2)
button3.place(x = 960, y = 700, anchor= 'center') # initiate button, dont worry about the window turning to (not responding) all its doing is the image comparing stuff
button4.config(text = "Options", command = options_menu) # options to change things
button4.place(x = 960, y = 780, anchor= 'center')
button5.config(text = "Exit", command = root.destroy) # exit button
button5.place(x = 960, y = 860, anchor= 'center')
print(leniancy)
def options_menu():
forgor() # resets all widgets
label1.config(text = "Image Leniency\n(the lower, the more accurate, while the higher, the more possible images detected)", font = (fonta, 20))
label1.place(x = 960, y = 100, anchor= 'center')
slider1.set(leniancy) # to set it to what was previously set, or the default
slider1.config(bd = 0 ,from_ = 1, to = 10, tickinterval = 1, variable = leniancy, length = 400, orient = HORIZONTAL, font = (fonta, 20), command = lenancy)
slider1.place(x = 960, y = 170, anchor= 'center')
button1.config(text = "Save & Exit", command = start1) #back to main menu
button1.place(x = 960, y = 860, anchor= 'center')
def start2(): # second part of the code [BUG] when you click the go button without specifying folders, it breaks. its an easy fix but thats not at the top of my list right now
global folder1, folder2
forgor()
folder1 = get_average_colors(file1)
folder2 = get_average_colors(file2)
for i in folder1.keys():
for j in folder2.keys():
compare_images(i, j)
showImages(identicalImages1[indecs], identicalImages2[indecs])
def ask_for_folder(folder):
global file1, file2
if folder == 1:
try:
file1 = filedialog.askdirectory().replace("\\", "/")
label2.config(text= file1[[i for i, c in enumerate(file1) if c == "/"][-1] + 1:])
except IndexError:
label2.config(text= '')
elif folder == 2:
try:
file2 = filedialog.askdirectory().replace("\\", "/")
label3.config(text= file2[[i for i, c in enumerate(file2) if c == "/"][-1] + 1:])
except IndexError:
label3.config(text= '')
def lenancy(value): # used in the menu
global leniancy
leniancy = value
def swag_sort(stri): # used for sorting images that were all saved as the same name, with the ending being an index of those images, so like: image (1).jpg
try:
return int(stri[stri.index('(') + 1:stri.index(')')])
except:
return stri
def remove_non_ascii(s): # removes all the weird characters that arent gonna work
try:
return "".join(c for c in s if ord(c)<128)
except:
return s
def tell_if_non_ascii(s):
for i in s:
if ord(i)>128:
return True
else:
return False
def round(x, interval): # the main way to change the leniency of image checking, for stuff like image corruption
return (-x % interval + x)
def get_average_colors(currentDirectory): # gets every image in the folder, divides those images by 4, then gets the average rgb color for the 4 quadrant images. the 4 quadrant stuff is usually to help greyscale images
global directories
average = {}
os.chdir(currentDirectory)
directories.append(currentDirectory)
list1 = [i for i in [i for i in [i for i in os.listdir(currentDirectory) if "." in i]] if i[i.index('.'):] not in blacklisted] # removes shortcuts and folders from the list of images
Placeholder = {}
for i in list1:
if tell_if_non_ascii(i):
Placeholder[i] = remove_non_ascii(i)
for i in Placeholder.keys():
os.rename(i,Placeholder[i])
list1 = [remove_non_ascii(i) for i in list1]
try:
list1 = sorted(list1, key=swag_sort)
except:
pass
for image in list1: # splits every image in the list into 4 parts, then gets the average pixel of each
print(image, end=" \r")
myimg = cv2.imread(image)
(h, w) = myimg.shape[:2]
(cX, cY) = (int(w) // 2, int(h) // 2)
imgs = [myimg[0:cY, 0:cX],myimg[0:cY, cX:w],myimg[cY:h, 0:cX],myimg[cY:h, cX:w]] # goes from top left, to top right, then bottom left, then bottom right
avg_color = []
for i in imgs:
avg_color_per_row = numpy.average(i, axis=0)
avg_color.append([round(i, leniancy) for i in numpy.average(avg_color_per_row, axis=0)])
average[image] = avg_color
return average
def compare_images(image1, image2): # image comparison algorithm
global identicalImages1, identicalImages2
list1 = folder1[image1]
list2 = folder2[image2]
p = []
for i, j in zip(list1, list2):
d = math.sqrt((i[0] - j[0])**2 + (i[1] - j[1])**2 + (i[2] - j[2])**2)
p.append(int((1 - d / (255 * math.sqrt(3))) * 100)) # stinky math, basically simplified version of a whole bunch of processes in one to get the percentage of how off it is
#if set(p) == {100}: #for correctness and nothing else
if p.count(100) >= 4: #1 should be changeable, and should be a weight if i ever am gonna find out how to correctly make an ai
identicalImages1.append(image1)
identicalImages2.append(image2)
print(str(p) + "100% chance of {} being a duplicate to {}".format(image1, image2))
else:
print(str(p) + "% chance of {} being a duplicate to {}".format(image1, image2), end=" \r")
return p
def showImages(img1, img2): # tkinter part that lets you compare images
forgor()
imag1 = (Image.open(directories[0] + '/' + img1))
imag2 = (Image.open(directories[1] + '/' + img2))
resized_image1 = imag1.resize((960, 540), Image.ANTIALIAS)
resized_image2 = imag2.resize((960, 540), Image.ANTIALIAS)
new_image1 = ImageTk.PhotoImage(resized_image1)
new_image2 = ImageTk.PhotoImage(resized_image2)
ratio = str(identicalImages1.index(img1)) + "/" + str(len(identicalImages1))
image1.place(x = 0, y = 20)
image1.config(image= new_image1) # image 1
image1.image = new_image1
image2.place(x = 960, y = 20)
image2.config(image= new_image2) # image 2
image2.image = new_image2
label1.place(x = 0, y = 20)
label1.config(font=(fonta, 20), text= str(img1)) #image 1 name, displayed in the top left corner of image 1
label2.place(x = 960, y = 20)
label2.config(font=(fonta, 20), text= str(img2)) #image 2 name, displayed in the top left corner of image 2
label3.place(x = 960, y = 530, anchor= 'center') # displays how far you are through the grading process
label3.config(font = (fonta, 20), text = ratio)
button1.place(x = 480, y = 590, anchor= 'center')
button1.config(font=(fonta, 20), text= "delete {}".format(str(img1)), command= lambda: destroyed_image(img1, directories[0], replaced())) # destroys the image1
button2.place(x = 1440, y = 590, anchor= 'center')
button2.config(font=(fonta, 20), text= "delete {}".format(str(img2)), command= lambda: destroyed_image(img2, directories[1], replaced())) # destroys the image2
button3.place(x = 960, y = 590, anchor= 'center')
button3.config(text = "pass", font=(fonta, 20), command= replaced) # passes both images
button4.place(x = 960, y = 670, anchor= 'center')
button4.config(text = "delete both", font=(fonta, 20), command= lambda: destroyed_image(img1, directories[0], destroyed_image(img2, directories[1], replaced()))) # runs the destroy twice with an, in my opinion, genius way to incorperate both and still replace the images
def replaced(): # when done with it
global indecs
indecs += 1
try:
showImages(identicalImages1[indecs], identicalImages2[indecs])
except IndexError: # when at the end of the list
start1()
def destroyed_image(imag, directory, diff): # destroys all the images that are detected simular ahead of it, if it was chosen to be deleted WORK IN PROGRESS
try:
for i in [index for index, element in enumerate(identicalImages1) if element == imag][1:]:
identicalImages1.pop(i)
identicalImages2.pop(i)
except:
try:
for i in [index for index, element in enumerate(identicalImages2) if element == imag][1:]:
identicalImages1.pop(i)
identicalImages2.pop(i)
except:
pass
try:
os.remove(directory + '/' + imag)
except:
print("image already deleted or doesnt exist")
diff
start1()
try:
mainloop()
except:
pass
i found the answer just a bit ago, apparently no matter the order you place it in, which ever widget was defined first goes on the bottom, and i put my labels to be defined first. so, the labels were, no matter what, being placed behind the image, and the image was resized so it still had the dimensions of the original image, just the pixels of the image were resized. so they would hide underneath the images no matter what.
Related
In my app, settings button are initiating a window, in that window you insert your link and this link need to get back to main function and work with button, which open this link in browser
from tkinter import *
from tkinter import messagebox
def validate(P):
if len(P) == 0:
return True
elif len(P) <= 10:
return True
else:
return False
def validate_en(s):
pass
def close():
if messagebox.askokcancel("Close window", "Are u sure you want to exit?"):
web.destroy()
if __name__ == "__main__":
web = Tk()
web.configure(background = "black")
web.title("WebSaver")
web.geometry("600x400")
web.iconbitmap('icon.ico')
web.resizable(False, False)
web.protocol("WM_DELETE_WINDOW", close)
def main_content():
web.withdraw()
main = Toplevel(web)
main.title("Application")
main.geometry("800x600")
main.iconbitmap('icon.ico')
main.protocol("WM_DELETE_WINDOW", close)
main.resizable(False, False)
canvas = Canvas(main,width = "800", height = "600", highlightthickness = 0, bg =
"black")
canvas.pack(fill = BOTH, expand = True)
upper_text = Label(canvas, text= "TEXT", justify = "center", background =
"black", foreground = "white", font = "KacstDigital, 20", borderwidth = 2,
highlightthickness = 1, highlightbackground = "gray")
upper_text.pack(padx = 5)
def link_1():
pass
button_1 = Button(canvas, text = "First link", bg = "#293133", fg = "white", font
= "KacstDigital, 18", height = 2, width = 15, command = lambda: link_1)
button_1.place(x = 30, y = 150)
button_conf_1 = Button(canvas, text = "settings", bg = "#293133", fg = "white",
font = "KacstDigital, 7", width = 7, command = configurate_button_1)
button_conf_1.place(x = 198, y = 203)
def configurate_button_1():
def close():
conf.destroy()
def apply(link):
if (link.isspace() or link == ""):
messagebox.showwarning(title = "Error!", message = "Input is null")
else:
close()
return link
conf = Toplevel(web)
conf.title("Application")
conf.geometry("600x100")
conf.iconbitmap('icon.ico')
conf.protocol("WM_DELETE_WINDOW", close)
conf.resizable(False, False)
canvas = Canvas(conf, width = "600", height = "100", highlightthickness = 0, bg =
"black")
canvas.pack(fill = BOTH, expand = True)
vcmd = (canvas.register(validate_en), '%s')
link_text = Label(canvas, text= "Link: ", justify = "center", background =
"black", foreground = "white", font = "KacstDigital, 12", borderwidth = 2,
highlightthickness = 1, highlightbackground = "gray")
link_text.place(x = 5, y = 10)
link_entry = Entry(canvas, bg = "#293133", fg = "white", font = "KacstDigital,
14", width = 45, validate = "key", validatecommand = vcmd)
link_entry.place(x = 78, y = 10)
link_button = Button(canvas, text = "Confirm changes", bg = "#293133", fg =
"white", font = "KacstDigital, 14", height = 1, width = 20, command = lambda:
apply(link_entry.get()))
link_button.place(x = 15, y = 50)
main_content()
web.mainloop()
I need help with getting value from link_entry (in conf.button func.) and give this value to main_content to open this link from main_content.
Sorry for this strange option strings, idk how to get them at the right place
i am making a movie recommendation GUI with the help of a dataset. For that, i need the value selected from the list by clickng on the recommedation button but i am not able to figure out to do so.
from tkinter import *
import pandas as pd
window = Tk()
window.config(background = 'white')
window.geometry('700x500')
title = Label(text = 'Movie Recommendation', font = ('times new roman',20),background = 'white')
title.pack()
label = Label(text = '**********************', font = ('times new roman',17),background = 'white' )
label.pack()
label = Label(text = 'Movie List :', font = ('times new roman',17),background = 'white' )
label.place(x = 5, y =66)
scroll_bar = Scrollbar(window)
scroll_bar.pack(side = RIGHT, fill = Y)
list = Listbox(window, yscrollcommand = scroll_bar.set, height = 21, width = 40, background = 'white', foreground = 'black' )
for i in df['title']:
list.insert(END,i)
list.place(x=5,y=105)
rec = Label(text = 'Recommended Movies :', font = ('times new roman',17),background = 'white')
rec.place(x = 300, y = 66)
def selected_item():
print(list.get(ANCHOR))
# selected = Label(text = selected_item(),font = ('times new roman',15))
# selected.place(x=300,y = 96)
def movie():
button = Button(text = "Recommendation",foreground='black', command = selected_item,background = 'white')
button.place(x=5,y=460)
movie()
window.mainloop()
this is my code.
i tried everything i could think of but i am new to coding. thank you.
My first post, so I apologize as I learn to use this. Also, I am sure my code is very jumbled and rudimentary, but I am not here to get someone to re-write my code. I have a question about how a widget is behaving and an error code I am getting.
I currently have two frames in a mainWindow, and when you click a button labeled "New", a small window (newWindow) pops up that has a registration form, and a button labeled "Register" to write the form data to a .txt file.
The problem I am having is that if I do not define where the button should go, it appears in the mainWindow. If I specify for it to appear in the newWindow, it does not appear and throws me the following error:
File
"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/init.py",
line 1507, in nametowidget
w = w.children[n] KeyError: '!button2'
Here is my code (get ready for a mess!):
from tkinter import *
from tkinter import ttk
from time import strftime
from tkmacosx import SFrame, Button
import tkinter as tk
mainWindow = Tk()
mainWindow.title('BATCO Main')
def createWindow():
#When createWindow() is called, the following code is executed, starting with creating the window object itself, which is set to the Tk() widget caller
newWindow = Tk()
# Add title of window
newWindow.title('Patron Entry')
# Set from and geometry of the Button (widthxheight+XPOS+YPOS)
newWindow.geometry('500x350+100+200')
# THIS PART CREATES AND APPENDS THE FILE FOR STORING NAMES:
def saveInfo():
# Defines Variables(3) for the "get" Method that will take from the StringVar Variables(2) above:
fname_info = fname.get()
mname_info = mname.get()
lname_info = lname.get()
suffix_info = suffix.get()
addr1_info = addr1.get()
addr2_info = addr2.get()
city_info = city.get()
state_info = state.get()
zipcode_info = zipcode.get()
print(fname_info, mname_info, lname_info, suffix_info, addr1_info, addr2_info, city_info, state_info, zipcode_info)
# This starts by opening the file 'patrons.txt' and assigns it to the file Variable. It uses the Arg 'a' which stands for Append, so it will add to the file.
file = open('patrons.txt', 'a')
# Once the file is open, write to it using the write method on the Variable file. The Write method accepts one Arg, so I have to use the + Operator to Concatenate text.
file.write (fname_info + ',')
file.write (mname_info + ',')
file.write (lname_info + ',')
file.write (suffix_info + ',')
file.write (addr1_info + ',')
file.write (addr2_info + ',')
file.write (city_info + ',')
file.write (state_info + ',')
file.write (zipcode_info + ';\n')
file.close ()
print (fname_info, 'has been registered')
# Clears the fields in the form
fname_entry.delete(0, END)
mname_entry.delete(0, END)
lname_entry.delete(0, END)
suffix_entry.delete(0, END)
addr1_entry.delete(0, END)
addr2_entry.delete(0, END)
city_entry.delete(0, END)
state_entry.delete(0, END)
zipcode_entry.delete(0, END)
# This code closes the window after entry
newWindow.destroy()
# End of saveInfo function
# Creating basic text that is formatted to be a header at the top of the window
lbl = Label(newWindow, text = 'Create Record', bg = 'light gray', fg = 'gray', width = '50', font = ('Arial', 17))
lbl.place(x=0, y=0)
# Defining Variables(1) for the text box labels:
fname_text = Label(newWindow, text = 'First Name', fg = 'gray', font = ('Arial', 12))
mname_text = Label(newWindow, text = 'Middle name', fg = 'gray', font = ('Arial', 12))
lname_text = Label(newWindow, text = 'Last Name', fg = 'gray', font = ('Arial', 12))
suffix_text = Label(newWindow, text = 'Suffix', fg = 'gray', font = ('Arial', 12))
addr1_text = Label(newWindow, text = 'Address 1', fg = 'gray', font = ('Arial', 12))
addr2_text = Label(newWindow, text = 'Address 2', fg = 'gray', font = ('Arial', 12))
city_text = Label(newWindow, text = 'City', fg = 'gray', font = ('Arial', 12))
state_text = Label(newWindow, text = 'State', fg = 'gray', font = ('Arial', 12))
zip_text = Label(newWindow, text = 'Zip', fg = 'gray', font = ('Arial', 12))
# Placing text box labels:
fname_text.place(x = 15, y = 50)
mname_text.place(x = 155, y = 50)
lname_text.place(x = 295, y = 50)
suffix_text.place(x = 435, y = 50)
addr1_text.place(x = 15, y = 100)
addr2_text.place(x = 15, y = 150)
city_text.place(x = 15, y = 200)
state_text.place(x = 318, y = 200)
zip_text.place(x = 367, y = 200)
# Defining and formatting Variables(2) for the data entered INTO the Entry boxes:
fname = StringVar()
mname = StringVar()
lname = StringVar()
suffix = StringVar()
addr1 = StringVar()
addr2 = StringVar()
city = StringVar()
state = StringVar()
zipcode = StringVar()
# Defining the Variables(3) for the Entry boxes:
fname_entry = Entry(newWindow, textvariable = fname, width = 14)
mname_entry = Entry(newWindow, textvariable = mname, width = 14)
lname_entry = Entry(newWindow, textvariable = lname, width = 14)
suffix_entry = Entry(newWindow, textvariable = suffix, width = 5)
addr1_entry = Entry(newWindow, textvariable = addr1, width = 51)
addr2_entry = Entry(newWindow, textvariable = addr2, width = 51)
city_entry = Entry(newWindow, textvariable = city, width = 32)
state_entry = Entry(newWindow, textvariable = state, width = 3)
zipcode_entry = Entry(newWindow, textvariable = zipcode, width = 13)
`enter code here`# Placing the Entry boxes:
fname_entry.place(x=15, y = 69)
mname_entry.place(x=155, y = 69)
lname_entry.place(x=295, y = 69)
suffix_entry.place(x=435, y = 69)
addr1_entry.place(x=15, y = 119)
addr2_entry.place(x=15, y = 169)
city_entry.place(x=15, y = 219)
state_entry.place(x=318, y = 219)
zipcode_entry.place(x=360, y = 219)
# Creates a Button and assigns it to the Variable: register. It is a gray, borderless button that when clicked, calls the saveInfo function.
register = Button(text = "REGISTER", bordercolor = 'gray', padx = 10, pady = 5, background='#BDBDBD', borderless = 'true', relief = 'groove', command = saveInfo)
# Places the Button
register.place (in_=newWindow, x = 200, y = 275)
newWindow.mainloop()
# End of createWindow function
style1 = ttk.Style()
style2 = ttk.Style()
style3 = ttk.Style()
style1.configure('topFrame.TFrame', background='green', borderwidth=4, relief='raised')
style2.configure('bottomFrame.TFrame', background = 'blue', borderwidth=6, relief = 'raised')
style3.configure('SrchLabel.TLabel')
eFrame = ttk.Frame(mainWindow, width=1060, height=200, style='topFrame.TFrame').grid()
rFrame = ttk.Frame(mainWindow, width=1060, height=600, style='bottomFrame.TFrame').grid()
# eFrame: Title text shown before the search terms entry box
srchFrame = ttk.Label(mainWindow, style = 'SrchLabel.TLabel', text = 'Patron Search')
srchFrame.place (x='30', y='40')
# eFrame: Search terms entry box
srchVar = StringVar()
srchEntry = tk.Entry(eFrame, bd = '1', width = '35')
srchEntry.place (x='130', y='37')
# eFrame: Button to execute Search
srchButton = Button(eFrame, text = 'Search', height = 30, width = 60, bd = '1')
srchButton.place(x = '470', y = '35')
# eFrame: Button to create New Record
newButton = Button(eFrame, text = 'New', height = 30, width = 60, bd = '1', command = createWindow)
newButton.place(x = '550', y = '35')
# rFrame: TAB Window Frame = from ttk Notebook
tabControl = ttk.Notebook(rFrame, width = 995, height = 528, style = 'rTabs.TNotebook')
# rFrame: TAB Elements
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tab3 = ttk.Frame(tabControl)
tab1=Frame(tabControl, background="#ffffff")
tab1.pack()
tab2=Frame(tabControl, background="#ffffff")
tab2.pack()
tab3=Frame(tabControl, background="#ffffff")
tab3.pack()
# rFrame: TAB Titles and Window placement
tabControl.add(tab1, text ='Patron')
tabControl.add(tab2, text ='Orders')
tabControl.add(tab3, text = 'Donations')
tabControl.place(x='5', y='205')
# TAB 1 Content
ttk.Label(tab1, text ='Patron Data').grid(column = 0, row = 0, padx = 30, pady = 30)
# TAB 2 Content
ttk.Label(tab2, text ='Order History and Info').grid(column = 0, row = 0, padx = 30, pady = 30)
# TAB 3 Content
ttk.Label(tab3, text ='Donation Info').grid(column = 0, row = 0, padx = 30, pady = 30)
# mainWindow: MENUBAR
menubar = Menu(mainWindow)
# mainWindow: Filemenu
file = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='File', menu = file)
file.add_command(label ='New File', command = None)
file.add_command(label ='Open...', command = None)
file.add_command(label ='Save', command = None)
file.add_separator()
file.add_command(label ='Exit', command = mainWindow.destroy)
# mainWindow: Editmenu
edit = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='Edit', menu = edit)
edit.add_command(label ='Cut', command = None)
edit.add_command(label ='Copy', command = None)
edit.add_command(label ='Paste', command = None)
edit.add_command(label ='Select All', command = None)
edit.add_separator()
edit.add_command(label ='Find...', command = None)
edit.add_command(label ='Find again', command = None)
# mainWindow: Helpmenu
help_ = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='Help', menu = help_)
help_.add_command(label ='Tk Help', command = None)
help_.add_command(label ='Demo', command = None)
help_.add_separator()
help_.add_command(label ='About Tk', command = None)
mainWindow.config(menu = menubar)
mainWindow.mainloop()
Again, I am not looking for advice on how to write better code, as I am just learning (2 weeks in). However any help you can provide in letting me know what I am doing wrong and where I can find an answer would be greatly appreciated!
Thanks in advance!
I'm new in Python, I am searching for solution with this error. I got stuck with this assignment.
I'm trying to change the description by each picture but unfortunately I failed.
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
root.title("Image Viewer")
root.config(bg = "Grey")
frame1 = Frame(root, width = 500, height = 325, bg = "Silver")
frame1.pack(side = TOP)
frame2 = Frame(root, width = 500, height = 25, borderwidth= 1, bg = "Grey")
frame2.pack(side = BOTTOM, pady= 2)
# Image:
img1 = ImageTk.PhotoImage(Image.open("dec19.jpg"))
img2 = ImageTk.PhotoImage(Image.open("dec20.jpg"))
img3 = ImageTk.PhotoImage(Image.open("dec21.jpg"))
# Description:
des1= Label(frame1, text = "I am happy this day")
des2= Label(frame1, text = "going somewhere")
des3= Label(frame1, text = "Today is a great day")
# , width = 500, height = 315
num = 1
# List:
img_list = [img1, img2,img3]
des_list = [1 , 2, 3]
# Startup:
my_label = Label(frame1,image = img1)
my_label.pack()
my_des = Label(frame1, text = f"Description{num}")
my_des.pack(side = BOTTOM)
# Definning Command functions:
def close_app():
exit()
def forward(image_num):
global my_label
global prev
global next1
global num
global my_des
global des_list
my_label.pack_forget()
# .grid_forget()
my_label = Label(frame1, image= img_list[image_num-1])
my_label.pack()
my_des.pack_forget()
my_des = Label(frame1, text = f"Description{des_list[image_num-1]}")
my_des.pack()
# .grid(row = 0, column = 0, columnspan = 3)
next1 = Button(frame2, text = "Next", command = lambda: forward(image_num+1))
next1.grid(row = 1, column = 2)
prev = Button(frame2, text = "Previous", command = lambda : back(image_num-1))
prev.grid(row = 1, column = 0)
if image_num == 3:
next1 = Button(frame2, text = "Next", state = DISABLED)
next1.grid(row = 1, column = 2)
prev = Button(frame2, text = "Previous", state = DISABLED, command =lambda : back(2))
prev.grid(row = 1, column = 0)
exits = Button(frame2, text = "Exit", command = close_app)
exits.grid(row = 1, column = 1)
next1 = Button(frame2, text = "Next", command = lambda: forward(2))
next1.grid(row = 1, column = 2)
root.mainloop()
If you want that each description is different you can create a dictionary wher you bind each image index to its description
image_description = {
1 : 'I am happy this day',
2 : "going somewhere",
3: "Today is a great day"
}
Now that you have this dictionary when you call the function that changes the image instead having a static string that changes only the number ( f"Description{des_list[image_num-1]}" ) you can get the datas from the dictionary
so change this 3 lines
my_des.pack_forget()
my_des = Label(frame1, text = f"Description{des_list[image_num-1]}")
my_des.pack()
to this
my_des.configure(text = f"{image_description[image_num]}")
When I run the code the box appears in the top left, with most out of the view of the screen. I have gone over the code and cannot find what it causing this. Thanks for any help.
from tkinter import *
import sqlite3
import LoginMenu
class LogOn:
def __init__(self, window):
self.window = window
window.title("Log On")
window.state("zoomed")
h = self.window.winfo_height()
w = self.window.winfo_width()
Center_h = h/2
Center_w = w/2
self.FrameLogOn = Frame(window, bg = "PaleTurquoise1")
self.FrameLogOn.place(x = Center_w , y = Center_h, anchor = "center")
self.lbl_TrainerID = Label(self.FrameLogOn, text = "TrainerID:", bg = "PaleTurquoise1", font =("Arial","16"), width = 15)
self.lbl_TrainerID.grid(row = 0, column = 0)
self.ent_TrainerID = Entry(self.FrameLogOn, bg = "PaleTurquoise1", font =("Arial","16"))
self.ent_TrainerID.grid(row = 0, column = 1)
self.lbl_TrainerIDError = Label(self.FrameLogOn, text = "*TrainerID Not Found" ,bg = "PaleTurquoise1", font =("Arial","16"), fg = "PaleTurquoise1", width = 15)
self.lbl_TrainerIDError.grid(row = 0, column = 2)
self.lbl_Password = Label(self.FrameLogOn, text = "Password:" ,bg = "PaleTurquoise1", font =("Arial","16"), width = 15)
self.lbl_Password.grid(row = 1, column = 0)
self.ent_Password = Entry(self.FrameLogOn, bg = "PaleTurquoise1", font =("Arial","16"))
self.ent_Password.grid(row = 1, column = 1)
self.lbl_PasswordError = Label(self.FrameLogOn, text = "*Incorrect Password" ,bg = "PaleTurquoise1", font =("Arial","16"), fg = "PaleTurquoise1", width = 15)
self.lbl_PasswordError.grid(row = 1, column = 2)
self.btn_LogIn = Button(self.FrameLogOn, text = "Log In", bg = "PaleTurquoise1", font =("Arial", "16"), width = 15, command = self.LogIn)
self.btn_LogIn.grid(row = 2, column = 0, columnspan = 3)
Instead of using place which is a bit complex, how about using pack? As I understand this is what you want:
self.FrameLogOn = Frame(window, bg = "PaleTurquoise1")
self.FrameLogOn.pack(expand=True)
Just replace
h = self.window.winfo_height()
w = self.window.winfo_width()
Center_h = h/2
Center_w = w/2
self.FrameLogOn.place(x = Center_w , y = Center_h, anchor = "center")
with self.FrameLogOn.pack(expand=True).
expand=True option will keep inner frame in the center of the window.
Your window isn't managed by a geometry manager yet and therefore winfo_width() and winfo_height() will return 1. If you add window.update_idletasks() before h = self.window.winfo_height() then the problem is solved. So like this:
window.state("zoomed")
window.update_idletasks()
h = self.window.winfo_height()
place lets you use relative coordinates. relx=.5, rely=.5, anchor="center" places a widget exactly in the middle of its master.