How to connect Fl_Text_Editor with output which is prodeced by a function? - python-2.7

I have a function which produces column of numbers:
def distancesplit(self):
img = np.asarray(Image.open("testtwo.tif").convert('L'))
img = 1 * (img < 127)
areasplit = np.split(img.ravel(), 24) # here we are splitting converted to 1D array
for i in areasplit:
area = (i == 0).sum()
print area
I want to output "area" result on Fl_Text_Editor widget. Here is the code I have now:
window = Fl_Window(100,100,400,400) # creating FLTK window
window.label(sys.argv[0])
button = Fl_Button(9,20,180,50) # making button class instance
button.label("Compute area")
button.callback(pixelarea) # connecting button to the function
button_two = Fl_Button(9,80,180,50)
button_two.label("Compute distances")
button_two.callback(distancesplit)
button_three = Fl_Button(9,140,180,50)
button_three.label("Compute features")
button_three.callback(distancetwo)
textedit = Fl_Text_Editor(9, 220, 180, 50)
textedit.buffer(self.textbuffer)
textedit.label("Text Editor")
textbuffer = Fl_Text_Buffer()
textbuffer.text("Code is written by the emotionally unstable alien who had survived space aircraft collision")
window.end() # code for running FLTK construction of widgets
window.show(len(sys.argv), sys.argv)
Fl.run() Thank you

Related

Trying to modify a code to capture an image every 15 minutes or so (time lapse)

Below code was taken from an existing post by Kieleth which I use as a subset of my larger codebase. I'm trying to leverage it to capture a list of frames taken once every thousand+ real time frames and later play in a time-lapse fashion. I've captured the frames but can't seem to view them when calling a simple function. I've seen in other posts that for loops are not recommended for this type of event but haven't figured out how to properly display. Any advise on this one would be appreciated?
from tkinter import ttk
import time
import cv2
from PIL import Image,ImageTk
#import threading
root = Tk()
def video_button1():# this flips between start and stop when video button pressed.
if root.video_btn1.cget('text') == "Stop Video":
root.video_btn1.configure(text = "Start Video")
root.cap.release()
elif root.video_btn1.cget('text') == "Start Video":
root.video_btn1.configure(text = "Stop Video")
root.cap = cv2.VideoCapture(0)
show_frame()
def show_frame():
# if video_btn1.cget('text') == "Stop Video":
global time_lapse_counter
ret, frame = root.cap.read()
if ret:
frame = cv2.flip(frame, 1) #flip image
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img) #converts img into tkinter readable format
root.video_label.imgtk = imgtk
if time_lapse_counter >= 20: # for Every 20 frames, capture one into time_lapse_list
time_lapse_list.append(imgtk)
time_lapse_counter = 0
root.video_label.configure(image=imgtk)
if len(time_lapse_list) == 5: # keep only 4 frames in the list *** debug purposes.
time_lapse_list.pop(0)
time_lapse_counter += 1
video_loop = root.after(40, show_frame)
else:
root.video_btn1.configure(text = "Start Video")
def time_lapse_play():
root.cap.release() #stop capturing video.
for image in time_lapse_list:
print (image, " ", len(time_lapse_list)," ",time_lapse_list) #
#*** I see the print of the pyimagexxx but nothing appears on the video***#
imgtk = image
root.video_label.imgtk = imgtk
root.video_label.configure(image=imgtk)
cv2.waitKey(500)
# video_loop = root.after(500, time_lapse_play)
def setup_widgets(): #simple label and 2 button widget setup
#Setup Top Right Window with pictures
f_width, f_height = 810, 475
root.rightframe= Frame(root, border=0, width=f_width, height = f_height)
root.rightframe.grid(row=0, column=0, padx=10, pady=0)
# Show video in Right Frame
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, f_width)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, f_height)
root.video_label = Label(root.rightframe)
root.video_label.grid(row=0, column = 0)
root.video_btn1 = Button(root.rightframe, fg='maroon', bg="yellow", text = "Stop Video", font=("Arial",10),height=0, width = 10, command=video_button1)
root.video_btn1.grid(row=0, column = 1)
root.video_btn2 = Button(root.rightframe, fg='maroon', bg="yellow", text="Time Lapse", font=("Arial",10),height=0, width = 10, command=time_lapse_play)
root.video_btn2.grid(row=1, column = 1)
# Main Code
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
screen_resolution = str(screen_width)+'x'+str(screen_height)
root.geometry(screen_resolution)
time_lapse_counter = 0
time_lapse_list=[]
setup_widgets()
show_frame()
root.mainloop()```
I've finally figure this one out. Seems that the for loop effectively doesn't work when using callback. I've modified the code to remove the for loop. I'm sure it could use some improvements but it works. I'm not sure how to reset the image count within the list as pop/append grows the list image number over time and I wonder about an overflow error. i.e after a few minutes, the list will contain [pyimage100 - pyimage200], after a few hours, [pyimage1000000 - pyimage1000100].
from tkinter import *
import cv2
from PIL import Image,ImageTk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg)
import matplotlib.pyplot as plt
root = Tk()
def video_button1():# this flips between start and stop when video button pressed.
if root.video_btn1.cget('text') == "Stop Video":
root.video_btn1.configure(text = "Start Video")
root.cap.release()
elif root.video_btn1.cget('text') == "Start Video":
root.video_btn1.configure(text = "Stop Video")
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 400)
show_frame()
def show_frame():
# if video_btn1.cget('text') == "Stop Video":
global time_lapse_counter
ret, frame = root.cap.read()
if ret:
frame = cv2.flip(frame, 1) #flip image
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img) #converts img into tkinter readable format
root.video_label.imgtk = imgtk
root.video_label.configure(image=imgtk)
if time_lapse_counter >= 20: # for Every 20 frames, capture one into time_lapse_list
time_lapse_list.append(imgtk)
time_lapse_counter = 0
if len(time_lapse_list) == 100: # keep 99 frames in the list
time_lapse_list.pop(0)
time_lapse_counter += 1
video_loop = root.after(40, show_frame)
else:
root.video_btn1.configure(text = "Start Video")
def time_lapse_play():
root.cap.release() #stop capturing video.
global frame_counter
if frame_counter <= len(time_lapse_list)-1:
imgtk = time_lapse_list[frame_counter] # get image from list
root.video_label.configure(image=imgtk) # update label with image from list
frame_counter += 1
video_loop = root.after(250, time_lapse_play) #wait 250ms until next frame
else:
frame_counter = 0 #reset frame_counter
def setup_widgets(): #simple label and 2 button widget setup
#Setup Top Right Window with pictures
f_width, f_height = 1200, 500
root.rightframe= Frame(root, border=0, width=f_width, height = f_height)
root.rightframe.grid(row=0, column=0, padx=10, pady=0)
# Show video in Right Frame
root.cap = cv2.VideoCapture(0)
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 400)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 400)
root.video_label = Label(root.rightframe)
root.video_label.grid(row=0, column = 0)
root.video_btn1 = Button(root.rightframe, fg='maroon', bg="yellow", text =
"Stop Video", font=("Arial",10),height=0, width = 10, command=video_button1)
root.video_btn1.grid(row=0, column = 1)
root.video_btn2 = Button(root.rightframe, fg='maroon', bg="yellow", text="Time Lapse", font=("Arial",10),height=0, width = 10, command=time_lapse_play)
root.video_btn2.grid(row=1, column = 1)
fig = plt.figure(1)
canvas = FigureCanvasTkAgg(fig, root.rightframe)
canvas.get_tk_widget().place(x=700,y=0)
canvas.get_tk_widget().config(border=2, bg="yellow", width=400, height=400)
# Main Code
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
screen_resolution = str(screen_width)+'x'+str(screen_height)
root.geometry(screen_resolution)
time_lapse_counter = 0
frame_counter = 0
time_lapse_list=[]
setup_widgets()
show_frame()
root.mainloop()
`

Python TkInter delete childs's grid

How can I clear the grid into a canvas in Tkinter?
Actually i have this :
photoCanvas = Canvas(photoFrame,bg='#E5E7E9')
rowPhoto = 0
columnPhoto = 0
for i in range(0, len(listPhotos), 1):
panel = Button(photoCanvas, image = listPhotos[i], borderwidth=0, height = 200, width = 200)
panel.grid(row=rowPhoto, column=columnPhoto, padx=5, pady=5, sticky="nsew")
if columnPhoto < 3:
columnPhoto += 1
else:
rowPhoto += 1
columnPhoto = 0
And i want to delete all my buttons.
Thx
If you want to delete all widgets inside another widget -- such as all buttons in your canvas -- you can simply iterate over all of the children of the widget and call the destroy method.
For example:
for widget in photoCanvas.winfo_children():
widget.destroy()

Tkinter cell location (x,y)?

Is there a way to get the cell size and x,y location of a cell's corner?I have radio buttons on the left side of my frame and I would like to resize an image based on the size of the frame.
What I'm going to end up doing is creating a block that takes up a large group of cells that will allow me to zoom in on my .tif and scroll left/right and up/down. Does this type of widget already exist?
Here's a very rough outline of what I currently have
from tkinter import *
from PIL import Image,ImageTk
import os
file_path = "C:/Users/..."
dirs = os.listdir(file_path)
root = Tk()
# Set window size slightly below screen size
width = int(root.winfo_screenwidth() - root.winfo_screenwidth()/9)
height = int(root.winfo_screenheight() - root.winfo_screenheight()/9)
root.geometry(str(width)+"x"+str(height))
class Application(Frame):
def __init__(self,master):
Frame.__init__(self,master)
os.chdir(file_path)
self.grid()
self.create_widgets()
def create_widgets(self):
Label(self,
text = "Available Files"
).grid(row=0,column=0,sticky=W)
Label(self,
text = "Select one:"
).grid(row=1,column=0,sticky=W)
self.filelist = StringVar()
self.filelist.set(0)
# Radio buttons of files in directory
i = 1
for files in dirs:
if os.path.isfile(os.path.join(file_path, files)):
i += 1
Radiobutton(self,
text=files,
variable=self.filelist,
value=files,
command=self.update_text
).grid(row=i,column=0,sticky=W)
# Message box
self.result = Text(self, width=40, height=5, wrap=WORD)
self.result.grid(row=i, column=0, columnspan=3)
def update_text(self):
message = "File selected is "
message += self.filelist.get()
self.display_image()
self.result.delete(0.0, END)
self.result.insert(0.0, message)
def display_image(self):
try:
self.image = Image.open(self.filelist.get())
except:
message += self.filelist.get() + " doesn't exist. This is awkward..."
img_width,img_height = self.image.size
self.preview_image = ImageTk.PhotoImage(self.image)
self.preview = Label(self, image=self.preview_image)
self.preview.grid(row=0, column=3, rowspan=20)
app = Application(root)
root.mainloop()

getting the value to the Entry using tkinter

I want to know how to display the values using Entry? i mean for instance if i have a function like:
def open():
path=tkFileDialog.askopenfilename(filetypes=[("Image File",'.jpg')])
blue, green, red = cv2.split(path)
total = path.size
B = sum(blue) / total
G = sum(green) / total
R = sum(red) / total
B_mean1.append(B)
G_mean1.append(G)
R_mean1.append(R)
blue.set(B_mean1)
green.set(G_mean1)
red.set(R_mean1)
root = Tk()
blue_label = Label(app,text = 'Blue Mean')
blue_label.place(x = 850,y = 140)
blue = IntVar(None)
blue_text = Entry(app,textvariable = blue)
blue_text.place(x = 1000,y = 140)
green_label = Label(app,text = 'Green Mean')
green_label.place(x = 850,y = 170)
green = IntVar(None)
green_text = Entry(app,textvariable = green)
green_text.place(x = 1000,y = 170)
red_label = Label(app,text = 'Red Mean')
red_label.place(x = 850,y = 200)
red = IntVar(None)
red_text = Entry(app,textvariable = red)
red_text.place(x = 1000,y = 200)
button = Button(app, text='Select an Image',command = open)
button.pack(padx = 1, pady = 1,anchor='ne')
button.place( x = 650, y = 60)
root.mainloop()
I have specified all the necessary imports and list variables. Still the value is not being displayed in the Entry field.
like if i get the value as :
blue mean = 37,
green mean = 36,
red mean = 41
and it will print in the console but not in the window. How can I achieve this?
Any suggestions are welcome!
Thanks for your supports!
Firstly I want to recommend that instead of using the place method you use the grid method. It is a lot faster and allows you to do things in a much more orderly fashion - especially in this application. Note that there are other geometry managers - like pack - which are good in yet other instances. Anyways, your GUI:
root = Tk()
blue_label = Label(root, text="Blue mean:")
blue_label.grid(row=1, column=1, sticky="w")
blue_entry = Entry(root)
blue_entry.grid(row=1, column=2)
green_label = Label(root, text="Green mean:")
green_label.grid(row=2, column=1, sticky="w")
green_entry = Entry(root)
green_entry.grid(row=2, column=2)
red_label = Label(root, text="Red mean:")
red_label.grid(row=3, column=1, sticky="w")
red_entry = Entry(root)
red_entry.grid(row=3, column=2)
root.mainloop()
That makes your GUI display nicely and without the manual geometry. Note that sticky just sets how the text is justified ("w" means west, and so the text justifies left).
Now, for actually displaying the text, all you have to do is:
blue_entry.insert(0, "blue-mean-value")
green_entry.insert(0, "green-mean-value")
red_entry.insert(0, "red-mean-value")
And if you are overwriting any text that is already there just do:
blue_entry.delete(0, END) # And green_entry and red_entry

Aligning Label in Frame Tkinter

I am new to Python and even newer to Tkinter.
I am currently practicing how to use Frames and Labels and
the problem I am encountering is, when I put Labels on a frame with some buttons next to each label,
the alignment is not good to look at.
Here is the code:
from Tkinter import *
class GUI():
def __init__(self):
self.namelist = ["Mark","Anna","Jason","Lenna","Leo","Zucharich","Robinson","AReallyLongNameThatMightExist"]
self.canvas = Canvas(width=1200,height=700)
self.canvas.pack(expand=YES,fill=BOTH)
def Friends(self):
controlframe = Frame(self.canvas)
controlframe.place(x=600,y=300)
#Frame for showing names of friends
for x in self.namelist:
frame = Frame(controlframe)
frame.pack()
Name = Label(frame,text="%s "%x).pack(side=LEFT)
chatButton = Button(frame,text="Chat").pack(side=LEFT)
delButton = Button(frame,text="Delete").pack(side=LEFT)
setcloseButton = Button(frame,text="Set Close").pack(side=LEFT)
setgroupButton = Button(frame,text="Set Group").pack(side=LEFT)
mainloop()
GUI = GUI()
GUI.Friends()
What should I do so that the alignment of the Label(=name) and the button is equal to the other ones so that they will form a shape of a rectangle and not some zigzag?
It is almost always better in Tk to use the grid geometry manager. It is much more flexible once you come to understand how it works. Converting your example to use grid solves your problem as shown below but you should experiment with it a bit. Try removing the 'sticky="W"' from the label for instance and see that the centering of the widgets within the row or column can be controlled. To get your frame responding to resizes sensibly you should investigate the columnconfigure and rowconfigure options for the grid geometry management as well.
from Tkinter import *
class GUI():
def __init__(self):
self.namelist = ["Mark","Anna","Jason","Lenna",
"Leo","Zucharich","Robinson",
"AReallyLongNameThatMightExist"]
self.canvas = Canvas(width=1200,height=700)
self.canvas.pack(expand=YES,fill=BOTH)
def Friends(self):
frame = Frame(self.canvas)
frame.place(x=600,y=300)
#Frame for showing names of friends
row = 0
for x in self.namelist:
label = Label(frame,text="%s "%x)
chatButton = Button(frame,text="Chat")
delButton = Button(frame,text="Delete")
setcloseButton = Button(frame,text="Set Close")
setgroupButton = Button(frame,text="Set Group")
label.grid(row=row, column=0, sticky="W")
chatButton.grid(row=row, column=1)
delButton.grid(row=row, column=2)
setcloseButton.grid(row=row, column=3)
setgroupButton.grid(row=row, column=4)
row = row + 1
mainloop()
GUI = GUI()
GUI.Friends()