Image won't display on tkinter canvas - python-3.x

I'm really hoping for some help on this as it has me absolutely stumped. I have the code working on its own as per below:
from tkinter import *
from PIL import ImageTk
dam_level = [75]
c = Canvas(width = 200, height = 235, relief = "sunken", borderwidth = 2)
c.grid(row = 11, rowspan = 8, column = 4, columnspan = 2)
c_width = 200
c_height = 250
y_stretch = 1.9
y_gap = 35
x_stretch = 15
x_width = 90
x_gap = 30
for x, y in enumerate(dam_level):
x0 = x * x_stretch + x * x_width + x_gap
y0 = c_height - (y * y_stretch + y_gap)
x1 = x * x_stretch + x * x_width + x_width + x_gap
y1 = c_height - y_gap
c.create_rectangle(x0, y0, x1, y1, fill = "#008ae8")
y = (str(y))
c.create_text(x0 + 10, y0, anchor = SW, text = (y, "%"))
c.create_text(x0 + 60, y1 + 5, anchor = N, text = "Catchment")
photo = ImageTk.PhotoImage(file =
"/Users/Name/Desktop/python3.4/water.png")
c.create_image(10, 10, image = photo, anchor = NW)
mainloop()
However when I put it in my main application in its own function (with the rest of my code), the image won't display. The graph and canvas displays, just not the water.png image. There's no error log or anything. The only change I make when I put this in my app is adding 'self' to this line. (And I remove the 'mainloop()' of course).
c = Canvas(self, width = 200, height = 235, relief = "sunken", borderwidth = 2)
Any suggestions would be greatly appreciated.

Thanks Bryan, for pointing me in the right direction.
Fixed with:
c.image = photo

Related

New FigureCanvasTkAgg always keeps a black border

I want to show some figures using tkinter, but new FigureCanvasTkAgg always keeps a black border. For example, I want to build two figures with red borders, but the new one has a black border, just like this:
enter image description here
But when the display window is not active, the black border disappear:
enter image description here
How to solve this problem? Thank you!
Here's the code:
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class display_window:
def __init__(self, width = 1024, height = 768):
self.figure_dict = {}
self.display_level = tk.Tk()
screen_width = self.display_level.winfo_screenwidth()
screen_height = self.display_level.winfo_screenheight()
init_position_x = int((screen_width - width) / 2)
init_position_y = int((screen_height - height) / 2)
position = str(width) + 'x' + str(height) + '+' + str(init_position_x) + '+' + str(init_position_y)
self.display_level.geometry(position)
self.x_offset = 120
self.y_offset = 10
self.figures_interval = 10
new_figure_button = tk.Button(self.display_level, text='new figure', command=self.new_figure_callback)
new_figure_button.place(x=5, y=5)
def new_figure_callback(self):
fig = Figure(figsize=(3, 2), dpi=100)
fig_plot = fig.add_subplot(111)
fig_plot.grid()
figure_canvas = FigureCanvasTkAgg(fig, self.display_level)
figure_widget = figure_canvas.get_tk_widget()
figure_widget.config(highlightthickness = 2, highlightbackground = "red", cursor='cross')
self.figure_dict[figure_widget] = {
"fig": fig,
"fig_plot": fig_plot,
"figure_canvas": figure_canvas,
}
self.arrange_figures(self.x_offset, self.y_offset, self.figures_interval)
def arrange_figures(self, x_offset, y_offset, figures_interval):
figures_area_width = self.display_level.winfo_width() - x_offset - figures_interval
figures_area_height = self.display_level.winfo_height() - y_offset - figures_interval
figure_count = len(self.figure_dict)
figure_width = figures_area_width
figure_height = (figures_area_height - figures_interval * (figure_count - 1)) / figure_count
for i, it in enumerate(self.figure_dict.keys()):
it.config(height = figure_height, width = figure_width)
it.place(x = x_offset, y = y_offset + i * (figure_height + figures_interval))
if __name__ == '__main__':
display_window()
tk.mainloop()
I want all the figures' borders display as in the config function.

How to automatically resize and centre tkinter window

I have an issues with window resizing in tkinter when a user variable is displayed. As the program takes in the name of a team and display's it later in the program, having a set size for the display window will not work as it needs to be adaptive. I have got code for centring the window, but is there a way to automatically set the size of the window?
Current Look:
team_2 = t2_entry.get()
top_2.withdraw()
confirm_screen = Toplevel(master)
w = 160 + len(team_2) + len(team_1)
h = 50
ws = confirm_screen.winfo_screenwidth()
hs = confirm_screen.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
confirm_screen.geometry('%dx%d+%d+%d' % (w, h, x, y))
t1_name = Label(confirm_screen, text = "Team 1: " + team_1).grid(row = 1, column = 1)
t2_name = Label(confirm_screen, text="Team 2: " + team_2).grid(row = 1, column = 2)
confirm_button = Button(confirm_screen, text = "Submit", width = 10, command = team_name_1).grid(row = 4, column = 1)
redo = Button(confirm_screen, text="Redo", width=10, command= lambda: [start_team1(), clear()]).grid(row=4, column=2)
Attempts 1:
team_2 = t2_entry.get()
top_2.withdraw()
confirm_screen = Toplevel(master)
w = 160 + len(team_2) + len(team_1)
h = 50
ws = confirm_screen.winfo_screenwidth()
hs = confirm_screen.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
confirm_screen.geometry('%dx%d+%d+%d' % (w, h, x, y))
t1_name = Label(confirm_screen, text = "Team 1: " + team_1).grid(row = 1, column = 1)
t2_name = Label(confirm_screen, text="Team 2: " + team_2).grid(row = 1, column = 2)
confirm_button = Button(confirm_screen, text = "Submit", width = 10, command = team_name_1).grid(row = 4, column = 1)
redo = Button(confirm_screen, text="Redo", width=10, command= lambda: [start_team1(), clear()]).grid(row=4, column=2)
Attempt 2:
team_2 = t2_entry.get()
top_2.withdraw()
confirm_screen = Toplevel(master)
w = confirm_screen.winfo_width
h = confirm_screen.winfo_height
ws = confirm_screen.winfo_screenwidth()
hs = confirm_screen.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
confirm_screen.geometry('%dx%d+%d+%d' % (w, h, x, y))
t1_name = Label(confirm_screen, text = "Team 1: " + team_1).grid(row = 1, column = 1)
t2_name = Label(confirm_screen, text="Team 2: " + team_2).grid(row = 1, column = 2)
confirm_button = Button(confirm_screen, text = "Submit", width = 10, command = team_name_1).grid(row = 4, column = 1)
redo = Button(confirm_screen, text="Redo", width=10, command= lambda: [start_team1(), clear()]).grid(row=4, column=2)
I think this is what you are after:
from tkinter import *
confirm_screen = Tk()
t1_name = Label(confirm_screen, text = "Team 1: " + "team_1").grid(row = 1, column = 1)
t2_name = Label(confirm_screen, text="Team 2: " + "team_2").grid(row = 1, column = 2)
confirm_button = Button(confirm_screen, text = "Submit", width = 10, command = None).grid(row = 4, column = 1)
redo = Button(confirm_screen, text="Redo", width=10, command= lambda: [start_team1(), clear()]).grid(row=4, column=2)
# You need to update the display so that the widgets are actually displayed on the screen.
# Otherwise `w` and `h` will both = 1
confirm_screen.update()
w = confirm_screen.winfo_width()
h = confirm_screen.winfo_height()
ws = confirm_screen.winfo_screenwidth()
hs = confirm_screen.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
confirm_screen.geometry('+%d+%d' % (x, y))
You have to first place all of the widgets and then calculate where the window should go. Also there is no need to always include the size of the window when using <tkinter.Tk>.geometry(...).

Attaching a scrollbar to a listbox

I know that there have been some other questions about this, but was hoping to get some help with my current frame configuration as seen below in the code snippet. I have also attached some images, first is with no scrollbar set up. Second is when I uncommented out my scrollbar code.
Frame setup:
# -- Top Frame -- #
self.top = Frame(master, height = 71, bg = self.topColor)
self.top.pack(fill = X)
self.bottom = Frame(master, height = 650, bg = self.bottomColor)
self.bottom.pack(fill = X)
Listbox setup:
# myscroll = Scrollbar(self.bottom, orient = VERTICAL)
Label(self.bottom, text = 'Files Chosen:', bg = self.bottomColor).place(x = 4, y = 110)
self.qListBox = Listbox(self.bottom, width = 30, selectmode = SINGLE) # I did have yscrollcommand = myscroll
# myscroll.config(command = self.qListBox.yview)
# myscroll.pack(side = RIGHT, fill = Y)
self.qListBox.place(x = 4, y = 130)
Label(self.bottom, text = 'Deployment Queue:', bg = self.bottomColor).place(x = 360, y = 110)
self.dListBox = Listbox(self.bottom, width = 30, selectmode = MULTIPLE)
self.dListBox.place(x = 360, y = 130)
Figured out how to resolve this. Created three frames that are inside of my master frame as seen below:
my_frame = Frame(self.master)
my_secondF = Frame(self.master)
my_thirdF = Frame(self.master)
Once I did this I simply put my Lisboxes inside of those frames and placed them accordingly and configured my scrollbars
self.qListBox = Listbox(my_frame, yscrollcommand=myscroll_bar, width = 32, selectmode = SINGLE)
I still, however, appreciate all the replies :)

stylegan encoder print image is too small

I am trying to print a stylemix encoder image however my printed images are too small, I am not sure where am I doing wrong.
my latent space
jon = np.load('latent_representations/example0.npy')
drogo = np.load('latent_representations/example1.npy')
# Loading already learned latent directions
smile_direction = np.load('ffhq_dataset/latent_directions/smile.npy')
gender_direction = np.load('ffhq_dataset/latent_directions/gender.npy')
age_direction = np.load('ffhq_dataset/latent_directions/age.npy'
)
my draw style mix loop
def draw_style_mixing_figure(png, Gs, w, h, src_dlatents, dst_dlatents, style_ranges):
print(png)
#src_dlatents = Gs.components.mapping.run(src_latents, None) # [seed, layer, component]
#dst_dlatents = Gs.components.mapping.run(dst_latents, None)
src_images = Gs.components.synthesis.run(src_dlatents, randomize_noise=False, **synthesis_kwargs)
dst_images = Gs.components.synthesis.run(dst_dlatents, randomize_noise=False, **synthesis_kwargs)
canvas = PIL.Image.new('RGB', (w * (len(src_dlatents) + 1), h * (len(dst_dlatents) + 1)), 'white')
for col, src_image in enumerate(list(src_images)):
canvas.paste(PIL.Image.fromarray(src_image, 'RGB'), ((col + 1) * w, 0))
for row, dst_image in enumerate(list(dst_images)):
canvas.paste(PIL.Image.fromarray(dst_image, 'RGB'), (0, (row + 1) * h))
row_dlatents = np.stack([dst_dlatents[row]] * len(src_dlatents))
row_dlatents[:, style_ranges[row]] = src_dlatents[:, style_ranges[row]]
row_images = Gs.components.synthesis.run(row_dlatents, randomize_noise=False, **synthesis_kwargs)
for col, image in enumerate(list(row_images)):
canvas.paste(PIL.Image.fromarray(image, 'RGB'), ((col + 1) * w, (row + 1) * h))
canvas.save(png)
return canvas.resize((512,512))
my printing image order
tflib.init_tf()
synthesis_kwargs = dict(output_transform=dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True), minibatch_size=1)
_Gs_cache = dict()
draw_style_mixing_figure(os.path.join(config.result_dir, 'style-mixing.png'), Gs, w=1024, h=1024, src_dlatents=jon.reshape((1, 12, 512)), dst_dlatents=drogo.reshape((1, 12, 512)), style_ranges=[range(1,1)]),
But resulting pictures are too small
any idea how to make them bigger?

Cannot remove 1px white strip - even after adding highlightthickness?

I followed this example since I was having issues removing white borders.
OP was told to add highlightthickness and change x0, y0 and y1 to 0. This worked all but for 1 px of white space/line? Any ideas? Thanks.
from tkinter import *
master = Tk()
master.configure(bg='#333333')
master.wm_attributes("-topmost", 1)
TopLevel.overrideredirect(True)
w = Canvas(master, width=150, height=40, bd=0, highlightthickness=0, relief='ridge',)
w.config()
w.pack(fill='both')
color = 100
x0 = 0
y0 = 0
x1 = 150
y1 = 0
while y0 < 20 :
r = color
g = color
b = color
rgb = r, g, b
Hex = '#%02x%02x%02x' % rgb
w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
color = color - 2
y0 = y0 + 1
y1 = y1 + 1
color = 10
while y0 < 40 :
r = color
g = color
b = color
rgb = r, g, b
Hex = '#%02x%02x%02x' % rgb
w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
color = color + 4
y0 = y0 + 1
y1 = y1 + 1
mainloop()
I changed the 4. and 7. line, because PyCharm gave me an error:
from tkinter import *
master = Tk()
tl = Toplevel() # delete me if the issue still remains :)
master.configure(bg='#333333')
master.wm_attributes("-topmost", 1)
tl.overrideredirect(True) # delete me if the issue still remains :)
...
if the issue still remains, try deleting 4. and 7. line.
Shouldn't make any problems

Resources