-1

I am trying to make an employee registration form in Tkinter and I have a problem inserting employee image to the canvas after browsing it from my pc

all I want to click the button under the canvas and browse for my image to automatically insert it to the canvas

from tkinter import *
import os
from tkinter import filedialog
from PIL import Image,ImageTk



def imageselect():
    global filepath
    filepath = filedialog.askopenfilename()
    entry.insert(END, filepath)
    return filepath


window = Tk()
btn = Button(window ,text = "select image",command = imageselect)
btn.pack()
x = StringVar()
entry= Entry(window,textvariable = x)
entry.pack(fill=X)
canvas = Canvas(window,width = 200,height = 200,bg="black")
img = PhotoImage(file=entry.get())
canvas.create_image(0,0,anchor=NW,image=img)
canvas.pack()

window.mainloop()
Alaa Ali
  • 1
  • 1
  • 1
    Can you please show us a [mre]? – TheLizzard Aug 19 '21 at 21:12
  • 1
    _"I have a problem"_ - what is the problem? – Bryan Oakley Aug 19 '21 at 21:13
  • This is an example if you run this script and browsing for picture it did not appear on the canvas – Alaa Ali Aug 19 '21 at 22:23
  • @AlaaAli because entry is empty at the time you try to get the path, also you don't need entry fo this – Matiiss Aug 19 '21 at 22:24
  • @AlaaAli Think about what your program is doing. First you create an entry, then you call `entry.get()` and then you allow the user to add data to the entry. The data that is added to the entry at the end isn't being used. Just handle the `filename` inside `imageselect`. Make sure to make `img` global. – TheLizzard Aug 19 '21 at 22:27
  • also why do you use `tkinter`'s `PhotoImage` if you have imported `Image` and `ImageTk`? also you shouldn't import everything (don't use `*` when importing), also you are not using `x` at all – Matiiss Aug 19 '21 at 22:29

1 Answers1

1

This code will give you a button under the canvas and allow you to insert image into canvas.

import tkinter as tk
from tkinter import filedialog as fido

class CanvasImage:

    def __init__(self, title = "Image Loader"):

        self.master = tk.Tk()
        self.master.withdraw()
        self.master.title(title)
        self.canvas = tk.Canvas(self.master)
        self.canvas.grid(row = 0, column = 0, sticky = tk.NSEW)
        self.image_button = tk.Button(
            self.master, font = "Helvetica 12",
            text = "Choose Image", command = self.choose_image)
        self.image_button.grid(row = 1, column = 0, sticky = tk.NSEW)
        self.master.update()
        self.master.resizable(False, False)
        self.master.deiconify()

    def choose_image(self):
        image_name = fido.askopenfilename(title = "Pick your image")
        print(image_name)
        if image_name:
            self.image = tk.PhotoImage(file = image_name, master = self.master)
            w, h = self.image.width(),self.image.height()
            self.canvas.config(width = w, height = h)
            self.canvas.create_image((0,0), image = self.image, anchor = tk.NW)

if __name__ == "__main__":
    loader = CanvasImage()
    loader.master.mainloop()
Derek
  • 1,916
  • 2
  • 5
  • 15
  • You could have made it ... maybe less complex like using only functions? but ... ok, this kinda (not 100% sure but will accept) does answer the question – Matiiss Aug 19 '21 at 23:23
  • Well it does keep the namespace clean. – Derek Aug 19 '21 at 23:43
  • of course, your answer is great, it answer the question, follows best practices (except for PEP 8 but whatever) and stuff, but it may be harder for beginners to understand it (I mean they should eventually learn it but while they haven't ...), just saying. For example they may struggle implementing other features now. Not that you have to but you could at least maybe add a little more explanation and/or add the functional approach too. – Matiiss Aug 19 '21 at 23:51