How to show multiple pictures in tkinter with function? - python-3.x

I want to show many pictures in my gui application. But according to Here I need to save those pictures as reference to my class. but I am confused how should I do it with many pictures?
This does not show any image on the opened Window
from tkinter import *
import tkinter
import os
from PIL import Image, ImageTk
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) + "/"
class GUI():
def __init__(self,file_list):
self.file_list = file_list
self.root=Tk()
self.canvas = Canvas(self.root, width=480, height=800)
self.canvas.pack()
def image_opener(self, filename):
opened_image = Image.open(CURRENT_DIR + "images/gui/" + filename)
photo_image = ImageTk.PhotoImage(opened_image)
return photo_image
def show_image1(self):
img = self.image_opener(files["img1"])
self.canvas.create_image(0, 0, image=img, anchor = NW, state = NORMAL)
def show_image2(self):
img = self.image_opener(files["img2"])
self.canvas.create_image(0, 0, image=img, anchor = NW, state = NORMAL)
def show_screens(self):
self.show_image1()
self.show_image2()
self.root.mainloop()
files = {
"img1":"image1.png",
"img2":"image2.png",
"img3":"image3.png",
"img4":"image4.png"
}
gui = GUI(files)
gui.show_screens()
When I change it to this it shows pictures in the window but is there any elegant way to do it with many pictures (maybe around 75) ?
from tkinter import *
import tkinter
import os
from PIL import Image, ImageTk
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) + "/"
class GUI():
def __init__(self,file_list):
self.file_list = file_list
self.root=Tk()
self.canvas = Canvas(self.root, width=480, height=800)
self.canvas.pack()
self.opened_image1 = Image.open(CURRENT_DIR + "images/gui/image1")
self.photo_image1 = ImageTk.PhotoImage(self.opened_image1)
self.opened_image2 = Image.open(CURRENT_DIR + "images/gui/image2")
self.photo_image2 = ImageTk.PhotoImage(self.opened_image2)
def show_image1(self):
self.canvas.create_image(0, 0, image=self.photo_image1, anchor = NW, state = NORMAL)
def show_image2(self):
self.canvas.create_image(0, 0, image=self.photo_image2, anchor = NW, state = NORMAL)
def show_screens(self):
self.show_image1()
self.show_image2()
self.root.mainloop()
files = {
"img1":"image1.png",
"img2":"image2.png",
"img3":"image3.png",
"img4":"image4.png"
}
gui = GUI(files)
gui.show_screens()

Related

Tkinter program displays blank screen on linux, works on windows

I've been writing this code for a slideshow program in Linux. The problem I'm having is that when run from a windows environment it works perfectly (Full-screen resized images), however when run from a virtual Linux (Ubuntu x64) environment a blank white canvas appears with no images being displayed.
The code:
from PIL import Image, ImageTk
import tkinter as tk
import os
import glob
import random
class App(tk.Tk):
def __init__(self, image_files, delay):
tk.Tk.__init__(self)
self.w = self.winfo_screenwidth()
self.h = self.winfo_screenheight()
self.overrideredirect(1)
self.geometry("%dx%d+0+0" % (self.w, self.h))
self.delay = delay
self.pictures = []
self.track_img_ndex = 0
for img in image_files:
self.pictures.append(img)
self.picture_display = tk.Label(self)
self.picture_display.pack(expand=True, fill="both")
def show_slides(self):
if self.track_img_ndex < len(self.pictures):
x = self.pictures[self.track_img_ndex]
self.track_img_ndex +=1
original_image = Image.open(x)
resized = original_image.resize((self.w, self.h),Image.ANTIALIAS)
new_img = ImageTk.PhotoImage(resized)
self.picture_display.config(image=new_img)
self.picture_display.image = new_img
self.title(os.path.basename(x))
self.after(self.delay, self.show_slides)
else:
print("End of list!")
delay = 5000
playlist = glob.glob(r'\mnt\hgfs\E\Images\*.*')
random.shuffle(playlist)
image_files = playlist
app = App(image_files, delay)
app.show_slides()
app.mainloop()
Any help would be appreciated!
winfo_screenwidth() and winfo_screenheight() give not correct display size on Linux. Use full-screen mode to fix it.
The code:
from PIL import Image, ImageTk
import tkinter as tk
import os
import glob
import random
class App(tk.Tk):
def __init__(self, image_files, delay):
tk.Tk.__init__(self)
# start window size (any)
self.w = 500
self.h = 500
self.attributes("-fullscreen", True) # Activate full-screen mode
# Change full-screen mode bind
self.bind("<F11>", lambda event: self.attributes("-fullscreen",
not self.attributes("-fullscreen")))
# Bind full-screen mode exit
self.bind("<Escape>", lambda event: self.attributes("-fullscreen", False))
self.geometry("%dx%d+100+100" % (self.w, self.h))
self.delay = delay
self.pictures = []
self.track_img_ndex = 0
for img in image_files:
self.pictures.append(img)
self.picture_display = tk.Label(self)
self.picture_display.pack(expand=True, fill="both")
def show_slides(self):
if self.track_img_ndex < len(self.pictures):
x = self.pictures[self.track_img_ndex]
self.track_img_ndex += 1
original_image = Image.open(x)
window_size_now = (self.winfo_width(), self.winfo_height()) # Getting current window size :
resized = original_image.resize(window_size_now, Image.ANTIALIAS)
new_img = ImageTk.PhotoImage(resized)
self.picture_display.config(image=new_img)
self.picture_display.image = new_img
self.title(os.path.basename(x))
self.after(self.delay, self.show_slides)
else:
print("End of list!")
_delay = 5000
playlist = glob.glob(r'/home/yaroslav_admin/PycharmProjects/LearnPython_01/imgs/*.*')
random.shuffle(playlist)
_image_files = playlist
app = App(_image_files, _delay)
app.after(100, app.show_slides) # delayed start,
# because tkinter need some time to count full-screen window size in main loop !
app.mainloop()

AttributeError: 'NoneType' object has no attribute 'read'.How to fix this error?

Traceback errorimport tkinter
import PIL
from tkinter import *
import tkinter.ttk as ttk;
from ttk import *
from tkinter import filedialog
from PIL import ImageTk, Image
class Root(Tk):
def init(self):
super(Root, self).init()
self.title("Brain Tumor Detection Using Deep learning")
self.minsize(400, 200)
# self.wm_iconbitmap('icon.ico')
self.labelFrame = ttk.LabelFrame(self, text = "Choose Here")
self.labelFrame.grid(column = 0, row = 5, padx = 150, pady = 150)
self.button()
def button(self):
self.button = ttk.Button(self.labelFrame, text = "Browse A File",command=self.open_img)
self.button.grid(column = 1, row = 1)
def fileDialog(self):
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select A File", filetype =
(("jpeg files","*.jpg"),("all files","*.*")) )
print(self.filename)
#print(self.filename)
#photo = PhotoImage(self.filename)
self.label = ttk.Label(self.labelFrame, text = "")
self.label.grid(column = 1, row = 2)
self.label.configure(text = self.filename)
``def open_img(self):
# Select the Imagename from a folder
x = self.fileDialog()
# print(x)
# opens the image
img = Image.open(x)
# resize the image and apply a high-quality down sampling filter
img = img.resize((250, 250), Image.ANTIALIAS)
# PhotoImage class is used to add image to widgets, icons etc
img = ImageTk.PhotoImage(img)
#imgs = Label(self, image=img)
#imgs.image = img
# create a label
panel = Label(root, image = img)
# set the image as img
panel.image = img
panel.grid(row = 2)

how to accept filename from user and save the sound file in python

i am trying to record sound from pyaudio in python and making a gui for the same.
my code run fine when i use datetime library and give the filename eg.sound_2020_21_04_03_40.wav which is current date,time but when i try to take the filename from user with tkinter (from tkinter.filedialog import asksaveasfile) it is saving the sound file but its empty with 0 bytes.
can any on e help me in this. this is my coding part of stop button which terminate the code and save the file.
import tkinter as tk
import threading
import pyaudio
import wave
from tkinter import *
import tkinter.font as font
from tkinter.filedialog import asksaveasfile
class App():
chunk = 1024
sample_format = pyaudio.paInt16
channels = 2
fs = 44100
frames = []
def __init__(self, master):
self.isrecording = False
myFont = font.Font(weight="bold")
self.button1 = tk.Button(main, text='Record',command=self.startrecording,height=2,width=20,bg='#0052cc', fg='#ffffff')
self.button2 = tk.Button(main, text='stop',command=self.stoprecording,height=2,width=20,bg='#0052cc', fg='#ffffff')
self.button1['font'] = myFont
self.button2['font'] = myFont
self.button1.place(x=30, y=30)
self.button2.place(x=280, y=30)
def startrecording(self):
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.sample_format,channels=self.channels,rate=self.fs,frames_per_buffer=self.chunk,input=True)
self.isrecording = True
print('Recording')
t = threading.Thread(target=self.record)
t.start()
def stoprecording(self):
self.isrecording = False
print('recording complete')
self.filename = asksaveasfile(initialdir = "/",title = "Save as",mode='w',filetypes = (("audio file","*.wav"),("all files","*.*")),defaultextension=".wav")
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.sample_format))
wf.setframerate(self.fs)
wf.writeframes(b''.join(self.frames))
wf.close()
main.destroy()
def record(self):
while self.isrecording:
data = self.stream.read(self.chunk)
self.frames.append(data)
main = tk.Tk()
main.title('recorder')
main.geometry('520x120')
app = App(main)
main.mainloop()
image is here
It's strange that no exceptions were risen, because when you call askopenfile(...) it returns a file object (and opens an empty file for reading - that file you have seen), but wave.open(...) expects a filename. To get it, you need to use askopenfilename(...) instead of askopenfile(...). And don't forget to import askopenfilename in the top of your code.
Here is the full code (I have refactored it according to PEP8):
import tkinter as tk
import threading
import pyaudio
import wave
from tkinter import *
import tkinter.font as font
from tkinter.filedialog import asksaveasfilename
class App():
chunk = 1024
sample_format = pyaudio.paInt16
channels = 2
fs = 44100
frames = []
def __init__(self, master):
self.isrecording = False
myFont = font.Font(weight="bold")
self.button1 = tk.Button(main, text='Record', command=self.startrecording,
height=2, width=20, bg='#0052cc', fg='#ffffff')
self.button2 = tk.Button(main, text='stop', command=self.stoprecording,
height=2, width=20, bg='#0052cc', fg='#ffffff')
self.button1['font'] = myFont
self.button2['font'] = myFont
self.button1.place(x=30, y=30)
self.button2.place(x=280, y=30)
def startrecording(self):
self.p = pyaudio.PyAudio()
self.stream = self.p.open(format=self.sample_format, channels=self.channels,
rate=self.fs, frames_per_buffer=self.chunk, input=True)
self.isrecording = True
print('Recording')
t = threading.Thread(target=self.record)
t.start()
def stoprecording(self):
self.isrecording = False
print('recording complete')
self.filename = asksaveasfilename(initialdir="/", title="Save as",
filetypes=(("audio file", "*.wav"), ("all files", "*.*")),
defaultextension=".wav")
wf = wave.open(self.filename, 'wb')
wf.setnchannels(self.channels)
wf.setsampwidth(self.p.get_sample_size(self.sample_format))
wf.setframerate(self.fs)
wf.writeframes(b''.join(self.frames))
wf.close()
main.destroy()
def record(self):
while self.isrecording:
data = self.stream.read(self.chunk)
self.frames.append(data)
print("does it")
main = tk.Tk()
main.title('recorder')
main.geometry('520x120')
app = App(main)
main.mainloop()

resizing image in tkinter for my browsing file code

how can I resize my image? here is my code..
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from PIL import Image, ImageTk
class Root(Tk):
def __init__(self):
super(Root, self).__init__()
self.title("Python Tkinter Dialog Widget")
self.minsize(640, 400)
self.labelFrame = ttk.LabelFrame(self, text = "Open File")
self.labelFrame.grid(column = 0, row = 1, padx = 20, pady = 20)
self.button()
def button(self):
self.button = ttk.Button(self.labelFrame, text = "Browse A File",command = self.fileDialog)
self.button.grid(column = 1, row = 1)
def fileDialog(self):
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select A File", filetype =
(("jpeg files","*.jpg"),("all files","*.*")) )
self.label = ttk.Label(self.labelFrame, text = "")
self.label.grid(column = 1, row = 2)
self.label.configure(text = self.filename)
img = Image.open(self.filename)
photo = ImageTk.PhotoImage(img)
self.label2 = Label(image=photo)
self.label2.image = photo
self.label2.grid(column=3, row=4)
root = Root()
root.mainloop()
You can either use Image.resize() which does not keep the image aspect ratio, or Image.thumbnail() which keeps the image aspect ratio:
img = Image.open(self.filename)
imgsize = (600, 400) # change to whatever size you want
#img = img.resize(imgsize)
img.thumbnail(imgsize)
photo = ImageTk.PhotoImage(img)

Display an array as an image Tkinter

I'm attempting to display an image from a compressed DICOM data array using tkinter. I compressed the image to an 8-bit numpy array. I know that the array can be visualized, as I have visualized it using both cv2 and matplotlib. Below is how I created the data:
import cv2
import numpy as np
import pydicom #https://pydicom.github.io/pydicom/stable/api_ref.html
import os
import glob
from PIL import Image, ImageTk
import PIL
import tkinter as tk
from pathlib import Path
path = Path("C:/Users/H61972/Desktop/1-1058/DICOM")
os.chdir( path )
os.getcwd()
print(__doc__)
#Get dicom files sorted by filename
def get_dicom():
return glob.glob("**/IM*",recursive=True)#slices
#return one file to be read at a time
def load_image(dicom):
ds = pydicom.read_file(dicom)
#print(ds.SliceLocation)
data = np.array(ds.pixel_array)
#data = data - np.min(data)
x = np.max(data)/255
data = data/x
data = np.clip(data, 0, 255)
return data
dicom = get_dicom()
def process_frame():
global data
frame = load_image(dicom[10])
frame = cv2.equalizeHist(frame)
frame = cv2.blur(frame,(5,5))
return frame
And below is the Tkinter gui I am building:
class mainWindow():
def __init__(self):
self.root = tk.Tk()
self.frame = tk.Frame(self.root, width=500, height=400)
self.frame.pack()
self.canvas = tk.Canvas(self.frame, width=500,height=400)
self.canvas.place(x=-2,y=-2)
data= process_frame()
self.im=Image.frombytes('L', (data.shape[1],data.shape[0]), data.astype('b').tostring())
self.photo = ImageTk.PhotoImage(image=self.im)
self.canvas.create_image(0,0,image=self.photo,anchor=tk.NW)
self.root.update()
self.root.mainloop()
mainWindow()
Any advice would be much appreciated!
I found a solution to most of my problem, however I have created a new problem in doing so. Now when I run the program I create an extra window. Here are my changes:
class DICOM(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)#initialized tkinter
container = tk.Frame(self)#define our tkinter container
container.pack(side ="top", fill="both", expand=True)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
self.frames = { }
#for F in (StartPage, Viewer):
frame = mainWindow(container, self)
self.frames[mainWindow] = frame
frame.grid(row =0, column =0, sticky ="nsew")
self.show_frame(mainWindow)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class mainWindow(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.root = tk.Toplevel(class_=self.controller)
# self.frame = tk.Frame(self.root)
# self.frame.pack()
self.canvas = tk.Canvas(self.root)
self.canvas.place(x=0,y=0)
data= process_frame()
self.im=Image.frombytes('L', (data.shape[1],data.shape[0]), data.astype('b').tostring())
self.photo = ImageTk.PhotoImage(image=self.im)
self.canvas.create_image(0,0,image=self.photo,anchor=tk.NW)
self.root.update()
#self.root.mainloop()
app = DICOM()
app.geometry("800x800")
app.title("Head CT Volumetric Analysis")
app.config(bg="gray")
app.mainloop()
How can I prevent this extra window from appearing?

Resources