Canvas on Tkinter has NameError

Asked 2 years ago, Updated 2 years ago, 379 views

Python 3.9.5 64-bit Windows 10 Home

Currently, I use Tkinter to read PDFs and create tools to edit (rotate, split, save, etc.).
In the middle of that, I would like to write a code saying that clicking on the button on the next page/previous page will move the page showing the PDF, but the loading is not working well.
The code you wrote is as follows (because the code is long, we omit some parts that are not involved in loading files):
"The flow is ""Click the read button→File selection screen is displayed→Read any PDF file→Pillow image resize→Display on screen."""
Although it is not in the code below, there is actually a page transition code, and the PDF displayed by clicking on the next/previous page is also moved.

import tkinter ask
import tkinter.filedialog
from PIL import Image, ImageTk
from pdf2 image import convert_from_path
canvas_width=500
canvas_height=500

def create_widgets(root):
    canvas=tk.Canvas(root, width=canvas_width, height=canvas_height, highlightthickness=0)
    canvas.grid (column=0, row=0)
    operation_frame=tk.Frame(root)
    operation_frame.grid (column=1, row=0)

    read_button=tk.Button(operation_frame, text='read', command=file_read)
    read_button.grid (column=0, row=0)

    next_button=tk.Button(operation_frame, text='Next Page', command=next_page, state=tk.DISABLED)
    next_button.grid (column=0, row=5)

    prev_button=tk.Button(operation_frame, text='Previous Page', command=prev_page, state=tk.DISABLED)
    prev_button.grid (column=0, row=6)

default file_read():
    path=tkinter.filedialog.askopenfilename(
        filetypes=[('PDF file', '*.pdf', ],
        title='File Selection',
    )

    size=(canvas_width, canvas_height)
    num_page=read(path,size)

    show_page = 0
    canvas.create_image(
        0, 0,
        image=get_image(show_page),
        anchor=tk.NW
    )

    change_state()

defread (path, size):
    pdf_path=path

    pillow_images=convert_from_path(
        pdf_path,
        poppler_path=r'C:\Program Files\poppler-22.04.0\Library\bin'
    )

    x_ratio=size[0]/pillow_images[0].width
    y_ratio=size[1]/pillow_images[0].height

    image_ratio=min(x_ratio,y_ratio)

    resize_size=(
        int(pillow_images[0].width*image_ratio),
        int(pillow_images[0].height*image_ratio)
    )

    images=[ ]
    for pillow_image in pillow_images:
        resize_image=pillow_image.resize(resize_size)
        tkinter_image=ImageTk.PhotoImage(resize_image, master=root)
        images.append(tkinter_image)

    return len (images)

def get_image(num):
    if num<0 or num>=len(images):
        return None

    return images [num]

root=tk.Tk()
PDFEditor=create_widgets(root)
root.mainloop()

However, when I ran it, I got an error that the canvas.create_image was not defined.

Exception in Tkinter callback
Traceback (most recent call last):
  File "c:\Users\owner\AppData\Local\Programs\Python\Python39\lib\tkinter\_init__.py", line 1892, in__call__
    return self.func(*args)
  File "C:\Users\owner\AppData\Local\Temp\ipykernel_10820\3221926224.py", line 11, in file_read
    canvas.create_image(
NameError: name 'canvas' is not defined

I think something is probably going on when defining or calling a function.
This is because at the beginning of writing without defining a function, it was read and displayed in PDF format.
I could see any page, so this time I was trying to define them as functions to accommodate all pages.
Therefore (I don't know how to put it into words) I felt that the canvas I wrote in create_widgets was not taken over when I moved from create_widgets to file_read.

How do I resolve this?

python tkinter

2022-10-23 16:00

1 Answers

canvas is the variable used in the function create_widgets.You need some ingenuity to use it with the function file_read.

If you want to pass it as an argument, for example: Ramda expression (lambda) to pass it to command on the spot.This lambda expression is in create_widgets, so you can refer to canvas.

def create_widgets(root):
    # Canvas definitions, etc.
    # Omitted...
    read_button=tk.Button(
        operation_frame,
        text = 'Read',
        command=lambda:file_read(canvas)
    )

# Omitted...

def file_read(canvas):
    # Omitted...

Another possible method is to define the function file_read itself in the function create_widgets.


2022-10-23 16:00

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.