I have made a pdf viewer using tkinter. I am wondering if I can let the pdf file 'pop out' using Toplevel() function. I tried to use lambda to try to incorporate the Toplevel() when using the button but the pop out window did not reflect anything. Here is the code I made:
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkPDFViewer import tkPDFViewer as pdf
import os
#make tk case
root = Tk()
root.geometry("1000x700+200+100")
root.title("PDF Viewer")
root.configure(bg="light blue")
#view frame
view_frame=Frame(root, bg="light blue", bd=5, width=400)
view_frame.pack(side=LEFT)
#to generate pop up window to view PDFs
def popup(filename):
win=Toplevel()
win.geometry("100x80")
win.title(filename)
v2=None
file = ''
#search for files
def viewpdf():
#make v2 global
global v2
filename=filedialog.askopenfilename(initialdir=os.getcwd(),
title="Select PDF File",
filetype=(("PDF File", ".pdf"),
("PDF File", ".PDF"),
("All File",".txt")))
if filename:
global file
file=filename
#destroy old file if it exists
if v2:
v2.destroy()
#create new pdf images
v1=pdf.ShowPdf()
#clear stored images
v1.img_object_li.clear()
#store new images
v2=v1.pdf_view(view_frame, pdf_location=open(filename,"r"),height=50, width=80)
v2.pack(pady=(0,0))
#set buttons
view_button=Button(view_frame, text='SEARCH FOR FILES', command=lambda: [viewpdf(), popup(file)], width=50, bd=5)
view_button.pack()
root.mainloop()
Update: I have tried adding tkinter.TopLevel() inside the def viewpdf() and it worked! I have deleted the def popup() as well.
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkPDFViewer import tkPDFViewer as pdf
import os
#make tk case
root = Tk()
root.geometry("1000x700+200+100")
root.title("PDF Viewer")
root.configure(bg="light blue")
#view frame
view_frame=Frame(root, bg="light blue", bd=5, width=400)
view_frame.pack(side=LEFT)
v2 = None
#search for files
def viewpdf():
#make v2 global
global v2
filename=filedialog.askopenfilename(initialdir=os.getcwd(),
title="Select PDF File",
filetype=(("PDF File", ".pdf"),
("PDF File", ".PDF"),
("All File",".txt")))
if filename:
#destroy old file if it exists
if v2:
v2.destroy()
#create new pdf images
v1=pdf.ShowPdf()
#clear stored images
v1.img_object_li.clear()
#set a new pop out window
newWindow=tkinter.Toplevel(view_frame)
#store new images
v2=v1.pdf_view(newWindow, pdf_location=filename, height=50, width=80)
v2.pack(pady=(0,0))
Related
I wanted to create a pdf converter app with python which converts images to pdf.
This is my code but it is only converting one image into pdf I tried many ways to fix it but none of them worked can anyone please help me because I want to convert multiple images into pdf but it is not working besides using for loop. I tried img2pdf but it giving alpha channel error and I am not able to solve that.
import PIL.Image
from tkinter import *
from tkinter import filedialog as fd
import PyPDF2
import img2pdf
from tkinter import ttk
root = Tk()
root.geometry('500x500')
root.resizable(0, 0)
filename = StringVar()
entry = Entry(root, width=50, textvariable=filename).place(x=115, y=250)
def Select_images():
global files
files = fd.askopenfilenames()
def select_dir():
global dir_name
dir_name = fd.askdirectory()
def submit():
global file_name
file_name = filename.get()
def create_pdf():
myfile=open(f'{dir_name}/{file_name}.pdf', 'wb+')
for image in files:
img=PIL.Image.open(image).convert('RGBA')
im1=img.convert('RGB')
im1.save(r'{}\{}.pdf'.format(dir_name,file_name))
myfile.close()
button = Button(root, text='Sumbit PDF Name', command=submit).place(x=200, y=300)
label = Label(root, text='Write PDF Name').place(x=210, y=215)
button1 = Button(root, text='Create File', command=create_pdf).place(x=215, y=335)
button2 = Button(root, text='Select Directory To Save File',command=select_dir).place(x=200, y=50)
button3 = Button(root, text='select Images', command=Select_images).place(x=235, y=100)
root.mainloop()
See if this helps you:
from tkinter import Tk, messagebox as mb, filedialog as fd
from tkinter.constants import DISABLED, NORMAL
from tkinter.ttk import Button, Label
from PIL import Image
import os
root = Tk()
root.title("Image to PDF converter")
root.geometry("500x500")
imglist = [] # For creating a list of images
fimgl = [] # List for storing multiple image names
png = True # If the image chosen is a .png file
def askfile():
global files, fimg, order, imglist, tm, png
files = fd.askopenfilenames(title="Choose images", filetypes=(("PNGs", "*.png"), ("JPGs", "*.jpg"), ("All Files", "*.*")))
for i in files:
fimgl.append(i)
if files:
for j in fimgl:
if j.endswith(".png"): # If the image is a PNG:
png = True
fnl = Label(root, text=j)
fnl.pack()
img = Image.open(j)
fimg = img.convert('RGB')
imglist.append(fimg)
p.config(state=NORMAL)
def convert_pdf():
global png
try:
if png:
imglist.pop()
saveloc = fd.asksaveasfilename(title="Save the PDF file")
if saveloc:
if saveloc.endswith(".pdf"):
pass
else:
saveloc = saveloc + ".pdf"
if os.path.exists(saveloc):
yn = mb.askyesno("Confirm Save As", f"{os.path.basename(saveloc)} already exists.\nDo you want to replace it?")
if yn:
os.remove(saveloc)
else:
convert_pdf()
fimg.save(saveloc, save_all=True, append_images=imglist)
mb.showinfo("Done!", "PDF file saved! Click 'OK' to open it")
os.startfile(saveloc)
root.quit()
except Exception as err:
mb.showerror("Error", err)
root.quit()
cb = Button(root, text="Add Files", command=askfile)
cb.pack(pady=20)
p = Button(root, text="Convert", command=convert_pdf, state=DISABLED)
p.pack(pady=20)
root.mainloop()
I'm new to Tkinter and I'm trying to create a simple Button that opens a file dialog box, where the user chooses which CSV file to open. Under the button there is a label that should display the file path for the file that was opened.
When I click on the button once, everything works as expected. However, if I click on it a second time and select a different file, the new filepath overlaps with the previous one, instead of replacing it.
Here is the code for the implementation function (please let me know if you need more bits of code for context):
def open_csv_file():
global df
global filename
global initialdir
initialdir = r"C:\Users\stefa\Documents\final project models\Case A"
filename = filedialog.askopenfilename(initialdir=initialdir,
title='Select a file', filetypes = (("CSV files","*.csv"),("All files","*.*")))
df = pd.read_csv(os.path.join(initialdir,filename))
lbl_ok = tk.Label(tab2, text = ' ') #tab2 is a ttk.Notebook tab
lbl_ok.config(text='Opened file: ' + filename)
lbl_ok.grid(row=0,column=1)
Here is how to do it with .config(), create the label instance just once (can then grid as much as you want but probably just do that once too), then just configure the text:
from tkinter import Tk, Button, Label, filedialog
def open_file():
filename = filedialog.askopenfilename()
lbl.config(text=f'Opened file: {filename}')
root = Tk()
Button(root, text='Open File', command=open_file).grid()
lbl = Label(root)
lbl.grid()
root.mainloop()
You can use a StringVar for this. Here is an example that may help you:
from tkinter import *
from tkinter.filedialog import askopenfilename
root = Tk()
root.geometry('200x200')
def openCsv():
csvPath.set(askopenfilename())
csvPath = StringVar()
entry = Entry(root, text=csvPath)
entry.grid(column=0, row=0)
btnOpen = Button(root, text='Browse Folder', command=openCsv)
btnOpen.grid(column=1, row=0)
root.mainloop()
How do I send send text from the label to entry box, or send directly the path of the image to entry box in tkinter?
from tkinter import *
from PIL import ImageTk,Image
from tkinter import filedialog
root = Tk()
def open():
root.filename = filedialog.askopenfilename(initialdir="/", title="Select A File",filetypes=(("jpg files", "*.jpg"), ("all files", "*.*")))
my_label = Label(root, text=root.filename).pack()
my_btn = Button(root, text="Open files", command=open).pack()
#entry box
txt2 = Entry(root)
txt2.place(x=10, y=45)
root.mainloop()
Did you mean get text in label and insert the text to an Entry?
If yes, you can just make a StringVar() in the Entry
For example like this:
from tkinter import * #For python 3
from Tkinter import * #For python 2
root = Tk()
txt = StringVar()
#For inserting text
txt.set("This is a label and an entry")
label = Label(root, textvariable=txt).pack()
entry = Entry(root, textvariable=txt).pack()
root.mainloop()
I want to make a floating text box with button that saves all text in text box to as a .txt file multiple lines and saves files named by time created as title and in folders created by month.
I would like the file name to be automated by the time it was created like this [9-21-19_3_00_am]
I so far got a button that calls another button that will save anything i write in that second window into a .txt file. it saves everything i write though as the file name not like a title or prompting me to name the file name and adding all text written as the body of .txt file
I wanted this to be able to store entries and organize them some way as the .txt files are created
import tkinter as tk
from tkinter import filedialog
from tkinter.filedialog import asksaveasfilename
win = tk.Tk()
HEIGHT = 700
WIDTH = 800
canvas = tk.Canvas( height=HEIGHT, width=WIDTH)
canvas.pack()
#
def send():
print("button clicked:")
def f():
def save():
a = t.get()
with open((a + '.txt'), 'w') as f:
f.write(a)
top = tk.Tk()
t = tk.StringVar(top)
tk.Entry(top, textvariable=t).pack()
tk.Button(top, text = 'Save as a file', command=save).pack()
win.configure(background="#808000")
frame1 = tk.Frame(win,width=1100, height=776,bg = '#ffffff',
borderwidth=1, relief="sunken")
scrollbar = tk.Scrollbar(frame1)
editArea = tk.Text(frame1, width=400, height=400, wrap="word",
yscrollcommand=scrollbar.set,
borderwidth=0, highlightthickness=0)
scrollbar.config(command=editArea.yview)
scrollbar.pack(side="right", fill="y")
editArea.pack(side="left", fill="both", expand=True)
frame1.place(x=1.0,y=1.0)
send = tk.Button(frame1,text="send", command=f)
send.place(relx=0.1, relwidth=0.1, relheight=0.1)
win.mainloop()
I am trying to bind a photo to the list box, but the photo does not appear.
I tried to take a specific photo path here. with the same code above (in the choosePhoto) and it worked. For some reason when in the code inside the function and is binding the function to the listBox, the photo does not appear.
My code:
from tkinter import *
from PIL import ImageTk, Image
from os import *
def openPath(path,listBox):
try:
path2=str(path)
list1= listdir(path2)
listBox.delete(0,END)
for i in range(len(list1)):
listBox.insert(i,list1[i])
except:
print("file does not exist")
def choosePhoto(event):
path=str(textFolder.get())+"\\"+str(listBoxPath.get(ACTIVE))
image1=ImageTk.PhotoImage(Image.open(path))
lbl.configure(image=image1)
print(path)
root = Tk()
root.geometry("450x600")
root.title("project image proccesor")
frame1=Frame(root,width=250,height=100)
frame1.pack(side=LEFT,fill=BOTH)
frame4=Frame(root,width=250,height=100)
frame4.pack(side=RIGHT,fill=BOTH)
lblFolder=Label(frame1,text="Enter folder path:")
lblFolder.grid(row=0,column=0)
textFolder=Entry(frame1,insertwidth=4)
textFolder.grid(rowspan=1,column=0)
listBoxPath=Listbox(frame1)
listBoxPath.grid(row=2)
bChoose=Button(frame1,text="Choose",command=lambda: openPath(textFolder.get(),listBoxPath)).grid(row=1,column=1)
lbl=Label(frame4, text="waiting for photo")
listBoxPath.bind('<<ListboxSelect>>', choosePhoto)
root.mainloop()
There are 3 issues I can see here in your code.
1st. You need to define image1 as a global because this image is currently a local variable in the function and once the function completes the images is deleted unless you define it in the global namespace.
2nd. Your label that is used for displaying the images has not yet been placed on the screen. You need to use some geometry manager (probably grid()) in this case to display the image.
3rd. You are currently using ACTIVE in your selection on the list box. This will results in you selecting what was active prior to you clicking instead of what you just clicked on.
Change this:
list_box_path.get(ACTIVE)
to this:
list_box_path.get(list_box_path.curselection())
I have cleaned up your code a bit to more closely fit the PEP8 standard and added some minor changes and reduced section of code that were not needed.
import tkinter as tk
from PIL import ImageTk, Image
from os import listdir
def open_path(path):
try:
list1 = listdir(path)
list_box_path.delete(0, "end")
for i in range(len(list1)):
list_box_path.insert(i, list1[i])
except:
print("file does not exist")
def choose_photo(event):
global image1
path = Image.open("{}\\{}".format(text_folder.get(), list_box_path.get(list_box_path.curselection())))
image1 = ImageTk.PhotoImage(path)
lbl.configure(image=image1)
root = tk.Tk()
root.geometry("450x600")
root.title("project image processor")
frame1 = tk.Frame(root, width=250, height=100)
frame4 = tk.Frame(root, width=250, height=100)
lbl_folder = tk.Label(frame1, text="Enter folder path:")
text_folder = tk.Entry(frame1, insertwidth=4)
list_box_path = tk.Listbox(frame1)
b_choose = tk.Button(frame1, text="Choose", command=lambda: open_path(text_folder.get()))
lbl = tk.Label(frame4, text="waiting for photo")
frame1.pack(side="left", fill="both")
frame4.pack(side="right", fill="both")
lbl_folder.grid(row=0, column=0)
text_folder.grid(rowspan=1, column=0)
list_box_path.grid(row=2)
b_choose.grid(row=1, column=1)
lbl.grid(row=0, column=0)
list_box_path.bind('<<ListboxSelect>>', choose_photo)
root.mainloop()