I would like to personalized a menu bar. For example I want to delete the border that appears around the tk.Menu widget (with the add_command() method)
That's my code (I'm using Windows 10)
import tkinter as tk
from tkinter import ttk
dark_grey = "#212121"
dark_blue="#102A43"
blue_1="#243B53"
root = tk.Tk()
root.state('zoomed')
container = tk.Frame(root, bg = dark_grey)
container.grid_rowconfigure(0, weight = 0)
container.grid_columnconfigure(0, weight = 1)
menu_frame = tk.Frame(container, bg = dark_blue)
menu1 = tk.Menubutton(menu_frame, text = "Menu1", bg = dark_blue, fg =
"white", activebackground = blue_1, activeforeground =
"white")
menu1.grid(row = 0, column = 0)
submenu1 = tk.Menu(menu1, tearoff = 0, bg = dark_blue,
activebackground= blue_1, fg = "white",borderwidth = 0, activeborderwidth= 0)
submenu1.add_command(label = "Option 1.1")
submenu1.add_command(label = "Option 1.2")
menu1.configure(menu = submenu1)
menu_frame.grid(row = 0, column = 0, sticky = "ew")
container.pack(fill = tk.BOTH, expand = "True")
root.mainloop()
My idea is to create a menu without using tk.Menu and tk.MenuButton. I would like "bind" an <Enter> event to a label, in order to create a sort of drop down under the label. Is it possible?
Question: Customized menu bar without using the widget tk.Menu?
This example uses a tk.Toplevel as a popup window and displays the added tk.Menubutton.
The Submenu follows ths defined Style of the Top tk.Menubutton.
TODO:
Close the Popup Window if clicked outside or another Top Menubutton.
Extend with other than only tk.Menubutton
Keyboard support
import tkinter as tk
class Menu:
def __init__(self, parent, **kwargs):
self._popup = None
self._menubutton = []
self.parent = parent
self.parent.bind('<Button-1>', self.on_popup)
def on_popup(self, event):
w = event.widget
x, y, height = self.parent.winfo_rootx(), self.parent.winfo_rooty(), self.parent.winfo_height()
self._popup = tk.Toplevel(self.parent.master, bg=self.parent.cget('bg'))
self._popup.overrideredirect(True)
self._popup.geometry('+{}+{}'.format(x, y + height))
for kwargs in self._menubutton:
self._add_command(**kwargs)
def add_command(self, **kwargs):
self._menubutton.append(kwargs)
def _add_command(self, **kwargs):
command = kwargs.pop('command', None)
menu = self.parent
mb = tk.Menubutton(self._popup, text=kwargs['label'],
bg=menu.cget('bg'),
fg=menu.cget('fg'),
activebackground=menu.cget('activebackground'),
activeforeground=menu.cget('activeforeground'),
borderwidth=0,
)
mb._command = command
mb.bind('<Button-1>', self._on_command)
mb.grid()
def _on_command(self, event):
w = event.widget
print('_on_command("{}")'.format(w.cget('text')))
self._popup.destroy()
if w._command is not None:
w._command()
Usage:
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry("200x200")
style = {'bg': "#102A43", 'fg': "white",
'activebackground': "#243B53", 'activeforeground': "white",
'borderwidth': 0}
menu1 = tk.Menubutton(self, text="Menu1", **style)
submenu1 = Menu(menu1)
submenu1.add_command(label="Option 1.1")
submenu1.add_command(label="Option 1.2")
menu1.grid(row=0, column=0)
menu2 = tk.Menubutton(self, text="Menu2", **style)
submenu2 = Menu(menu2)
submenu2.add_command(label="Option 2.1")
submenu2.add_command(label="Option 2.2")
menu2.grid(row=0, column=2)
if __name__ == "__main__":
App().mainloop()
Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6
Related
So, I'm following a tutorial on making a simple calculator, and I'm Getting an attribute error AttributeError:'_tkinter.tkapp' object has no attribute 'displayframe' , apparently, the attribute doesn't exist in the source code even if it has been defined? would be grateful if someone helped
from tkinter import *
SMALL_FONT_STYLE = "Arial 16"
LIGHT_GRAY = "#F5F5F5"
LABEL_COLOR = "#25265E"
LARGE_FONT_STYLE = "Arial 40 bold"
WHITE = "#FFFFFF"
class Calculator(Tk):
def __init__(self):
super().__init__()
self.geometry("375x677")
self.resizable(0,0)
self.title("Calculator")
self.total_expression = "0"
self.current_expression = "0"
self.total_label, self.label = self.create_display_labels()
self.digits = {7:(1,1), 8:(1,2), 9:(1,3), 4:(2,1), 5:(2,2), 6:(2,3), 1:(3,1),2:(3,2), 3:(3,3), 0:(4,2), '.':(4,1)}
self.create_digits_buttons()
self.display_frame = self.create_display_frame()
self.buttons_frame = self.create_buttons_frame()
def create_display_labels(self):
total_label = Label(self.display_frame, text=self.total_expression, anchor=E, bg=LIGHT_GRAY, fg=LABEL_COLOR, padx=24, font=SMALL_FONT_STYLE)
total_label.pack(expand=True, fill="both")
label = Label(self.display_frame, text=self.total_expression, anchor=E, bg=LIGHT_GRAY, fg=LABEL_COLOR, padx=24, font=LARGE_FONT_STYLE)
label.pack(expand=True, fill="both")
return total_label, label
def create_display_frame(self):
frame = Frame(self, height=221, bg=LIGHT_GRAY)
frame.pack(expand=True, fill="both")
return frame
def create_buttons_frame(self):
frame = Frame(self)
frame.pack(expand=TRUE, fill="both")
return frame
def create_digits_buttons(self):
for digit, grid_value in self.digits.items():
button = Button(self.buttons_frame, text= str(digit), bg=WHITE, fg=LABEL_COLOR)
button.grid(row = grid_value[0], column = grid_value[1], sticky=NSEW)
if __name__ == '__main__':
Calc = Calculator()
Calc.mainloop()```
This error is because you call self.create_display_labels() before calling self.create_display_frame(). You also call self.create_digits_buttons() before calling self.create_buttons_frame().
Move self.create_display_labels() and self.create_digits_buttons() below self.create_display_frame() and self.create_buttons_frame(). Here is what __init__() should look like:
def __init__(self):
super().__init__()
self.geometry("375x677")
self.resizable(0,0)
self.title("Calculator")
self.total_expression = "0"
self.current_expression = "0"
self.digits = {7:(1,1), 8:(1,2), 9:(1,3), 4:(2,1), 5:(2,2), 6:(2,3), 1:(3,1),2:(3,2), 3:(3,3), 0:(4,2), '.':(4,1)}
self.display_frame = self.create_display_frame()
self.buttons_frame = self.create_buttons_frame()
self.create_digits_buttons() ### MOVED THIS LINE
self.total_label, self.label = self.create_display_labels() ### MOVED THIS LINE
I would like the user to write the recipe for a food and select which tab it will go on, how can I connect this and the recipe appears on the selected tab?
Code:
from tkinter import *
from tkinter import Tk
from tkinter import ttk
import tkinter as tk
class RecipesScreen():
def __init__(self):
self.root = tk.Tk()
self.window_recipes()
self.window_frame_recipes()
self.widget_frame_recipes()
self.root.mainloop()
def window_recipes(self):
self.root.title("Bom de Prato")
self.root.geometry("800x600")
self.root.resizable(False, False)
def window_frame_recipes(self):
self.tabs = ttk.Notebook(self.root) # Abas
self.tabs.place(x = 0, y = 0, width = 800, height = 600)
# Create Frame
self.frame_healthy = Frame(self.tabs)
self.frame_vegetarian = Frame(self.tabs)
self.frame_vegan = Frame(self.tabs)
self.frame_fastFood = Frame(self.tabs)
self.frame_diabetics = Frame(self.tabs)
self.frame_add_recipes = Frame(self.tabs)
self.tabs.add(self.frame_healthy, text='healthy')
self.tabs.add(self.frame_vegetarian, text='Vegetarian')
self.tabs.add(self.frame_vegan, text='Vegan')
self.tabs.add(self.frame_fastFood, text='Fast Food')
self.tabs.add(self.frame_diabetics, text='Diabetics')
self.tabs.add(self.frame_add_recipes, text='Add New Recipe')
def widget_frame_recipes(self):
# Create Label
self.lb_add_new_recipe = Label(self.frame_add_recipes, text='Add New Recipe', font='arial 20')
self.lb_where = Label(self.frame_add_recipes, text='Where do you like to add this recipe?', font='arial 10')
self.lb_add_new_recipe.place(relx=0.36, rely=0)
self.lb_where.place(relx=0, rely=0.10)
# Drop Down Button
self.Tipvar = StringVar(self.frame_add_recipes)
self.TipV = ("Healthy", "Vegetarian", "Fast Food", "Diabetics")
self.Tipvar.set("Healthy")
self.popupMenu = OptionMenu(self.frame_add_recipes, self.Tipvar, *self.TipV)
self.popupMenu.place(relx= 0.30, rely= 0.10, relwidth= 0.15, relheight= 0.05)
RecipesScreen()
You will need to make a dictionary or some other kind of mapping to associate the string with the corresponding Frame. You could do this manually, but it would be neater to back up and create the Frames from the list so that you get the dictionary from the creation process.
from tkinter import ttk
import tkinter as tk
TipV = ("Healthy", "Vegetarian", 'Vegan', "Fast Food", "Diabetics")
class RecipesScreen():
def __init__(self):
self.root = tk.Tk()
self.window_recipes()
self.window_frame_recipes()
self.widget_frame_recipes()
self.root.mainloop()
def window_recipes(self):
self.root.title("Bom de Prato")
self.root.geometry("800x600")
self.root.resizable(False, False)
def window_frame_recipes(self):
self.tabs = ttk.Notebook(self.root) # Abas
self.tabs.place(x = 0, y = 0, width = 800, height = 600)
# Create Frames
self.frames = {}
for catagory in TipV:
f = tk.Frame(self.tabs)
self.tabs.add(f, text=catagory)
self.frames[catagory] = f
self.frame_add_recipes = tk.Frame(self.tabs)
self.tabs.add(self.frame_add_recipes, text='Add New Recipe')
def widget_frame_recipes(self):
# Create Label
self.lb_add_new_recipe = tk.Label(self.frame_add_recipes, text='Add New Recipe', font='arial 20')
self.lb_where = tk.Label(self.frame_add_recipes, text='Where do you like to add this recipe?', font='arial 10')
self.lb_add_new_recipe.place(relx=0.36, rely=0)
self.lb_where.place(relx=0, rely=0.10)
# Drop Down Button
self.Tipvar = tk.StringVar(self.frame_add_recipes)
self.Tipvar.set("Healthy")
self.popupMenu = tk.OptionMenu(self.frame_add_recipes, self.Tipvar, *TipV)
self.popupMenu.place(relx= 0.30, rely= 0.10, relwidth= 0.15, relheight= 0.05)
btn = tk.Button(self.frame_add_recipes, text="Add", command=self.add)
btn.pack()
def add(self):
selected_frame = self.frames[self.Tipvar.get()]
lbl = tk.Label(selected_frame, text="you added a recipe")
lbl.pack()
RecipesScreen()
BTW, I highly recommend you back up and remove any use of place(). Use pack() and / or grid() to layout your widgets. Using place() will make your code very buggy and hard to maintain.
My code:
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.top = tkinter.Frame(self.main)
self.mid = tkinter.Frame(self.main)
self.latinword1 = tkinter.Button(self.mid, text = 'sinister', command = self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text = 'dexter', command = self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text = 'medium', command = self.cbfunction3)
self.toplabel = tkinter.Label(self.top, text= 'Latin')
self.toplabel2 = tkinter.Label(self.top, text= '\tEnglish')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.bot, textvariable = self.value)
self.labels1 = tkinter.Label(self.bot, textvariable = self.value1)
self.labels2 = tkinter.Label(self.bot, textvariable = self.value2)
self.labels.pack()
self.labels1.pack()
self.labels2.pack()
self.top.pack()
self.mid.pack()
self.latinword1.pack()
self.latinword2.pack()
self.latinword3.pack()
self.toplabel.pack(side='left')
self.toplabel2.pack(side='left')
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value1.set(value)
def cbfunction2(self):
value = 'right'
self.value.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Unexpected output:
Expected output:
As you can see, I am trying to get my expected output with 3 buttons that can show the English word after its being pressed. But I got my output vertically with my own code. I am expecting my button and the matched word are on same horizontal level. Can anyone help me with this issue? Thanks.
It is better to put all the labels and buttons in same frame and use grid() instead of pack():
import tkinter
class latinwords:
def __init__(self):
self.main = tkinter.Tk()
self.mid = tkinter.Frame(self.main)
self.mid.pack()
self.latinword1 = tkinter.Button(self.mid, text='sinister', command=self.cbfunction)
self.latinword2 = tkinter.Button(self.mid, text='dexter', command=self.cbfunction2)
self.latinword3 = tkinter.Button(self.mid, text='medium', command=self.cbfunction3)
self.toplabel = tkinter.Label(self.mid, text='Latin')
self.toplabel2 = tkinter.Label(self.mid, text='English')
self.value = tkinter.StringVar()
self.value1 = tkinter.StringVar()
self.value2 = tkinter.StringVar()
self.labels = tkinter.Label(self.mid, textvariable=self.value)
self.labels1 = tkinter.Label(self.mid, textvariable=self.value1)
self.labels2 = tkinter.Label(self.mid, textvariable=self.value2)
self.labels.grid(row=1, column=1)
self.labels1.grid(row=2, column=1)
self.labels2.grid(row=3, column=1)
self.latinword1.grid(row=1, column=0)
self.latinword2.grid(row=2, column=0)
self.latinword3.grid(row=3, column=0)
self.toplabel.grid(row=0, column=0)
self.toplabel2.grid(row=0, column=1)
tkinter.mainloop()
def cbfunction(self):
value = 'left'
self.value.set(value)
def cbfunction2(self):
value = 'right'
self.value1.set(value)
def cbfunction3(self):
value = 'centre'
self.value2.set(value)
s = latinwords()
Solution:
The self.bot attribute is missing.
self.bot = tkinter.Frame(self.main)
You should set the position of packing of frames.
self.top.pack(side=tkinter.TOP)
self.mid.pack(side=tkinter.LEFT)
self.bot.pack(side=tkinter.RIGHT)
Test/Output:
>>> python3 test.py
NOTE:
The order of English words are not correct but it is not related to question.
I recommend to use the grid instead of pack. You can make more nice GUI with grid in your case. See more: https://tkdocs.com/tutorial/grid.html
I have an "add task" button in my frame, which creates a new text widget to enter some text, with addition of text widgets the frame keeps expanding vertically
I've tried using resizable(False, False), it's showing
AttributeError: '_tkinter.tkapp' object has no attribute 'resizable'
class Container(tk.Frame):
def __init__(self, parent = None, priority = 3, bg = 'bisque'):
tk.Frame.__init__(self, parent)
self.f = tk.Frame(parent)
self.f.configure(bg = bg)
self.f.pack(fill = 'both', expand = True)
self.tk.resizable(False, False)
if __name__ == '__main__':
window = tk.Tk()
window.geometry('300x200-400+75')
window.minsize(300, 600)
p1 = Container(window, priority = 1)
p2 = Container(window, bg = 'blue', priority = 2)
p3 = Container(window, bg = 'red', priority = 3)
window.mainloop()
You can't use self.tk.resizable(False, False) for frame widget, it is only for the main window.
Solution
If you just want to make the frame not resizable when you add widgets to your frame use self.propagate(0) this will not let the children widgets to take over the size of the parent.
But If you want your main window not to resize then use window.resizable(False, False)
Code
import tkinter as tk
class Container(tk.Frame):
def __init__(self, parent = None, priority = 3, bg = 'bisque'):
tk.Frame.__init__(self, parent)
self.f = tk.Frame(parent)
self.f.configure(bg = bg)
self.propagate(0)
self.f.pack(fill = 'both', expand = True)
if __name__ == '__main__':
window = tk.Tk()
window.geometry('300x200+400+75')
window.minsize(300, 600)
# Use this if you don't want the main window to be resizable.
# window.resizable(False, False)
p1 = Container(window, priority = 1)
p2 = Container(window, bg = 'blue', priority = 2)
p3 = Container(window, bg = 'red', priority = 3)
window.mainloop()
Forgive me in advance for my code, but I'm simply making this for friend of mine to automatically populate a GUI interface with song information, channel information for each song, and things such as images attached to the songs. Right now I'm only scraping from a playlist on Youtube and a playlist on Soundcloud. I have all of that properly working, but me being new to frontend development left me in a horrible spot to make a decent application for him. I had a lot in mind that I could have done, but now I'm simply creating buttons with each song title as the text. Here is an image of my progress. I still have to find a way to attach each image to each button for the on_enter event, but that is for later on. As you can see, I have a on_leave function commented out. I was using that to delete the self.image_window each time I left a button. Problem is even a minuscule amount of mouse movement would cause the window to be delete and recreated dozens of times. How do I make it static so when I am hovering over a button it doesn't spam create/delete the window?
Thanks!
from Tkinter import *
import json
import os
import webbrowser
class GUIPopulator(Frame):
def __init__(self, parent):
Frame.__init__(self)
self.parent = parent
self.configure(bg='PeachPuff2')
self.columnconfigure(20, weight=1)
self.rowconfigure(30, weight=1)
self.curtab = None
self.tabs = {}
self.pack(fill=BOTH, expand=1, padx=5, pady=5)
self.column = 0
self.row = 0
def on_enter(self, event):
self.image_window = Toplevel(self)
self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
self.img = PhotoImage(file=self.img_path)
#self.image_window.minsize(width=200, height=250)
self.image_window.title("Preview")
canvas = Canvas(self.image_window, width=200, height=200)
canvas.pack()
canvas.create_image(100, 100, image=self.img)
#def on_leave(self, enter):
def addTab(self, id):
tabslen = len(self.tabs)
tab = {}
if self.row < 30:
btn = Button(self, text=id,highlightbackground='PeachPuff2' ,command=lambda: self.raiseTab(id))
btn.grid(row=self.row, column=self.column, sticky=W+E)
btn.bind("<Enter>", self.on_enter)
#btn.bind("<Leave>", self.on_leave)
tab['id']=id
tab['btn']=btn
self.tabs[tabslen] = tab
self.raiseTab(id)
self.row +=1
else:
self.row = 0
self.column +=1
btn = Button(self, text=id,highlightbackground='PeachPuff2' ,command=lambda: self.raiseTab(id))
btn.grid(row=self.row, column=self.column, sticky=W+E)
tab['id']=id
tab['btn']=btn
self.tabs[tabslen] = tab
self.raiseTab(id)
def raiseTab(self, tabid):
with open(os.getcwd() + '/../PlaylistListener/CurrentSongs.json') as current_songs:
c_songs = json.load(current_songs)
print(tabid)
if self.curtab!= None and self.curtab != tabid and len(self.tabs)>1:
try:
#webbrowser.open(c_songs[tabid]['link'])
webbrowser.open_new('http://youtube.com')
except:
pass
def main():
root = Tk()
root.title('Playlist Scraper')
root.geometry("1920x1080+300+300")
t = GUIPopulator(root)
with open(os.getcwd() + '/../PlaylistListener/CurrentSongs.json') as current_songs:
c_songs = json.load(current_songs)
for song in c_songs:
t.addTab(song)
root.mainloop()
if __name__ == '__main__':
main()
Example of JSON file provided:
{
"F\u00d8RD - Shadows (feat. Samsaruh)": {
"page_title": "youtube",
"link": "youtube.com/watch?v=CNiV6Pne50U&index=32&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"id": "CNiV6Pne50U",
"channel": "youtube.com/watch?v=CNiV6Pne50U&index=32&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"image_path": [
"http://i4.ytimg.com/vi/CNiV6Pne50U/hqdefault.jpg",
"CNiV6Pne50U.jpg"
]
},
"Katelyn Tarver - You Don't Know (tof\u00fb remix)": {
"page_title": "youtube",
"link": "youtube.com/watch?v=7pPNv38JzD4&index=43&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"id": "7pPNv38JzD4",
"channel": "youtube.com/watch?v=7pPNv38JzD4&index=43&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"image_path": [
"http://i4.ytimg.com/vi/7pPNv38JzD4/hqdefault.jpg",
"7pPNv38JzD4.jpg"
]
},
"Illenium - Crawl Outta Love (feat. Annika Wells)": {
"page_title": "youtube",
"link": "youtube.com/watch?v=GprXUDZrdT4&index=7&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"id": "GprXUDZrdT4",
"channel": "youtube.com/watch?v=GprXUDZrdT4&index=7&list=PLkx04k4VGz1tH_pnRl_5xBU1BLE3PYuzd",
"image_path": [
"http://i4.ytimg.com/vi/GprXUDZrdT4/hqdefault.jpg",
"GprXUDZrdT4.jpg"
]
}
}
After some testing I have come up with some code I think you can use or is what you are looking for.
I have changes a few things and add some others.
1st we needed to create a place holder for the top window that we can use later in the code. So in the __init__ section of GUIPopulatior add self.image_window = None. We will talk about this part soon.
next I created the image path as a class attribute on init this can be changed later with update if need be.
next I added a bind() to the init that will help us keep the self.image_window placed in the correct location even if we move the root window. so we add self.parent.bind("<Configure>", self.move_me) to the __init__ section as well.
next we create the method move_me that we just created a bind for.
the way it is written it will only take effect if self.image_window is not equal to None this should prevent any errors while self.image_window is being used however I have not created the error handling to deal with what happens after the toplevel window is closed by the user. Its not difficult but I wanted to answer for the main issue at hand.
Here is the move_me method:
def move_me(self, event):
if self.image_window != None:
h = self.parent.winfo_height() # gets the height of the window in pixels
w = self.parent.winfo_width() # gets the width of the window in pixels
# gets the placement of the root window then uses height and width to
# calculate where to place the window to keep it at the bottom right.
self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
self.parent.winfo_y() + h - 250))
next we need to modify the on_enter method to create the toplevel window if out class attribute self.image_window is equal to None if it is not equal to None then we can use the else portion of the if statement to just update the image.
Here is the modified on_enter method:
def on_enter(self, event):
if self.image_window == None:
self.image_window = Toplevel(self)
#this keeps the toplevel window on top of the program
self.image_window.attributes("-topmost", True)
h = self.parent.winfo_height()
w = self.parent.winfo_width()
self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
self.parent.winfo_y() + h - 250))
self.img = PhotoImage(file=self.img_path)
self.image_window.title("Preview")
self.canvas = Canvas(self.image_window, width=200, height=200)
self.canvas.pack()
self.canv_image = self.canvas.create_image(100, 100, image=self.img)
else:
self.img = PhotoImage(file= self.img_path)
self.canvas.itemconfig(self.canv_image, image = self.img)
all that being said there are some other issues with your code that need to be addressed however this answer should point you in the right direction.
Below is a section of your code you need to replace:
class GUIPopulator(Frame):
def __init__(self, parent):
Frame.__init__(self)
self.parent = parent
self.configure(bg='PeachPuff2')
self.columnconfigure(20, weight=1)
self.rowconfigure(30, weight=1)
self.curtab = None
self.tabs = {}
self.pack(fill=BOTH, expand=1, padx=5, pady=5)
self.column = 0
self.row = 0
def on_enter(self, event):
self.image_window = Toplevel(self)
self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
self.img = PhotoImage(file=self.img_path)
#self.image_window.minsize(width=200, height=250)
self.image_window.title("Preview")
canvas = Canvas(self.image_window, width=200, height=200)
canvas.pack()
canvas.create_image(100, 100, image=self.img)
#def on_leave(self, enter):
With this:
class GUIPopulator(Frame):
def __init__(self, parent):
Frame.__init__(self)
self.parent = parent
self.configure(bg='PeachPuff2')
self.columnconfigure(20, weight=1)
self.rowconfigure(30, weight=1)
self.curtab = None
self.image_window = None
self.img_path = os.getcwd() + '/Rotating_earth_(large).gif'
self.tabs = {}
self.pack(fill=BOTH, expand=1, padx=5, pady=5)
self.parent.bind("<Configure>", self.move_me)
self.column = 0
self.row = 0
def move_me(self, event):
if self.image_window != None:
h = self.parent.winfo_height()
w = self.parent.winfo_width()
self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
self.parent.winfo_y() + h - 250))
def on_enter(self, event):
if self.image_window == None:
self.image_window = Toplevel(self)
self.image_window.attributes("-topmost", True)
h = self.parent.winfo_height()
w = self.parent.winfo_width()
self.image_window.geometry('+{}+{}'.format(self.parent.winfo_x() + w - 250,
self.parent.winfo_y() + h - 250))
self.img = PhotoImage(file=self.img_path)
self.image_window.title("Preview")
self.canvas = Canvas(self.image_window, width=200, height=200)
self.canvas.pack()
self.canv_image = self.canvas.create_image(100, 100, image=self.img)
else:
self.img = PhotoImage(file= self.img_path)
self.canvas.itemconfig(self.canv_image, image = self.img)