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
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
.
© 2024 OneMinuteCode. All rights reserved.