Commit 75eca498 authored by Alessandro dos Santos Ferreira's avatar Alessandro dos Santos Ferreira
Browse files

Pynovisao - Classes Tk

parent 1b74267e
......@@ -33,17 +33,17 @@ def open_image(tk):
if event.xdata != None and event.ydata != None and int(event.ydata) != 0:
x = int(event.xdata)
y = int(event.ydata)
tk.write_logger("Coordinates: x = %d y = %d ", x, y)
tk.write_log("Coordinates: x = %d y = %d ", x, y)
if segments is not None:
tk.append_logger("Segment = %d", segments[y, x])
tk.append_log("Segment = %d", segments[y, x])
imagename = tk.utils.ask_image_name()
if imagename:
image = f.open_image(imagename)
name = f.get_filename(imagename)
tk.write_logger("Opening %s...", name)
tk.write_log("Opening %s...", name)
tk.add_image(image, name, onclick)
const_image = image
......@@ -56,11 +56,22 @@ def rotate_image(tk):
image = f.rotate_image(const_image)
tk.write_logger("Rotating image 90 degrees")
tk.write_log("Rotating image 90 degrees")
tk.refresh_image(image)
const_image = image
def rotate_image(tk):
global image, const_image
if const_image is None:
raise IException("Image not found")
image = f.rotate_image(const_image)
tk.write_log("Rotating image 90 degrees")
tk.refresh_image(image)
const_image = image
def close_image(tk):
global const_image
......@@ -68,7 +79,7 @@ def close_image(tk):
raise IException("Image not found")
if tk.close_image():
tk.write_logger("Closing image...")
tk.write_log("Closing image...")
const_image = None
segments = None
......@@ -79,11 +90,11 @@ def run_segmentation(tk):
if const_image is None:
raise IException("Image not found")
tk.write_logger("Running %s,,,", segmenter.get_name())
tk.write_log("Running %s,,,", segmenter.get_name())
tk.append_logger("\nConfig: %s", str(segmenter.get_summary_config()))
tk.append_log("\nConfig: %s", str(segmenter.get_summary_config()))
segments, image, run_time = segmenter.run(const_image)
tk.append_logger("\nTime elapsed: %0.3f seconds", run_time)
tk.append_log("\nTime elapsed: %0.3f seconds", run_time)
tk.refresh_image(image)
......@@ -91,7 +102,7 @@ def config_segmentation(tk):
global segmenter
title = "Configuring %s" % segmenter.get_name()
tk.write_logger(title)
tk.write_log(title)
current_config = segmenter.get_config()
......@@ -99,10 +110,15 @@ def config_segmentation(tk):
new_config = tk.get_config_and_destroy()
segmenter.set_config(new_config)
tk.append_logger("\nConfig updated: %s", str(segmenter.get_summary_config()))
tk.append_log("\nConfig updated: %s", str(segmenter.get_summary_config()))
tk.dialogue_config(title, current_config, process_config)
def refresh_classes(tk):
tk.write_log("Refreshing classes...")
tk.add_panel_classes()
def func_not_available(tk):
tk.write_logger("This functionality is not available right now.")
tk.write_log("This functionality is not available right now.")
......@@ -14,31 +14,19 @@ else:
import tkinter as Tk
import tkMessageBox
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import pylab as plt
from Interface import Interface, InterfaceException as IException
from tk_interface import *
from tk import *
class TkInterface(Interface):
utils = TkUtils.TkUtils
utils = TkUtils.Utils
title = None
__root = None
__menus = None
__configs = None
__im = None
__canvas = None
__logger = None
__dialog = None
__image = None
__grid = None
def __init__(self, title):
......@@ -56,7 +44,7 @@ class TkInterface(Interface):
def add_menu(self, label):
self.__menus.append( Menu.Menu(label) )
self.__menus.append( TkMenu.Menu(self.__root, label) )
def add_command(self, label, action, shortcut = None):
self.__menus[-1].add_command( label = label, action = lambda *_: self.__apply( action ), shortcut = shortcut )
......@@ -66,165 +54,137 @@ class TkInterface(Interface):
def render_menu(self):
menubar = Tk.Menu(self.__root)
shortcuts = []
for menu in self.__menus:
menubar = menu.render(menubar)
shortcuts += menu.get_shorcuts()
menu.render(menubar)
self.__root.config(menu=menubar)
for sh in shortcuts:
self.__root.bind("<Control-Key-" + sh["shortcut"] + ">", sh["action"])
self.__root.bind("<Control-Key-" + sh["shortcut"].lower() + ">", sh["action"])
def show(self):
self.__root.protocol("WM_DELETE_WINDOW", self.quit)
self.__root.mainloop()
def add_image(self, image, title = None, onclick = None):
if self.__canvas is None:
self.__root.image = image
fig = plt.figure(facecolor='white')
self.__im = plt.imshow(self.__root.image) # later use a.set_data(new_data)
#ax = plt.gca()
#ax.set_xticklabels([])
#ax.set_yticklabels([])
# a tk.DrawingArea
self.__canvas = FigureCanvasTkAgg(fig, master=self.__root)
self.__canvas.show()
self.__canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
if self.__image is None:
self.__image = TkCanvas.Image(self.__root, image, lambda event, *_: self.__apply( onclick, event ))
else:
self.__image.refresh(image)
if onclick is not None:
fig.canvas.mpl_connect('button_press_event', func = lambda event, *_: self.__apply( onclick, event ))
if title is not None:
self.set_subtitle(title)
def refresh_image(self, image, title = None):
if self.__image is not None:
self.__image.refresh(image)
if title is not None:
self.set_subtitle(title)
else:
self.refresh_image(image, title)
def refresh_image(self, image, title = 'None'):
if self.__canvas is not None:
self.__root.image = image
self.__im.set_data(self.__root.image)
self.__canvas.draw()
def close_image(self):
if self.__canvas is not None:
if self.__image is not None:
if tkMessageBox.askokcancel("Quit", "Do you want to close the image?"):
self.__root.image = None
#self.__im.set_data(np.zeros((0,0,3), float))
#self.__canvas.draw()
self.__canvas.get_tk_widget().pack_forget();
self.__canvas.get_tk_widget().destroy();
self.__image.close()
self.__im = None
self.__canvas = None
self.__image = None
return True
return False
def create_logger(self):
self.__logger = Tk.Text(self.__root, width=0, height=10, bg="white", fg="black", padx=5, pady=5)
self.__logger.insert(Tk.INSERT, "$ Pynovisao is ready!\n")
self.__logger.config(state=Tk.DISABLED)
self.__logger.pack(side=Tk.BOTTOM, fill=Tk.X, expand=False)
def write_logger(self, fmt, *args):
self.clean_logger()
self.append_logger(fmt % args)
def open_log(self):
self.__logger = TkLogger.Logger(self.__root)
def append_logger(self, fmt, *args):
self.__logger.config(state=Tk.NORMAL)
self.__logger.insert(Tk.END, fmt % args)
self.__logger.insert(Tk.END, '\n')
self.__logger.config(state=Tk.DISABLED)
def write_log(self, fmt, *args):
if self.__logger:
self.__logger.write_logger(fmt, *args)
def clean_logger(self):
self.__logger.config(state=Tk.NORMAL)
self.__logger.delete('1.0', Tk.END)
self.__logger.insert('1.0', '$ ')
self.__logger.config(state=Tk.DISABLED)
def append_log(self, fmt, *args):
if self.__logger:
self.__logger.append_logger(fmt, *args)
def destroy_logger(self):
self.__logger.pack_forget();
self.__logger.destroy();
def clear_log(self):
if self.__logger:
self.__logger.clear_logger()
def close_log(self):
if self.__logger:
self.__logger.destroy_logger()
def popup(self):
pass
def log_and_popup(self, message):
pass
def add_panel(self, left = True):
self.__grid = TkCustomFrame.CustomGrid(self.__root, 175)
def show_error(self, fmt, *args):
tkMessageBox.showerror("Error", fmt % args)
side = Tk.LEFT if left == True else Tk.RIGHT
self.__grid.pack(side=side, fill=Tk.Y, expand=False)
def show_info(self, fmt, *args):
tkMessageBox.showinfo("Info", fmt % args)
def add_panel_classes(self, classes = None):
if self.__grid is None:
self.__grid = TkCustomFrame.CustomGrid(self.__root)
else:
self.clear_panel_classes()
def show_warning(self, fmt, *args):
tkMessageBox.showwarning("Warning", fmt % args)
def dialogue_config(self, title, configs, callback):
n_configs = len(configs)
from random import randint as r
length = r(2, 16)
self.__grid.add_cell_label("Classes ", 0, 0, 12, 4)
self.__dialog = Tk.Toplevel(self.__root, padx=10, pady=10)
self.__dialog.title(title)
for i in range(1, length):
self.__grid.add_cell_radio_button("Classe " + str(i), i, i, 0, 12, selected=False if i > 1 else True)
self.__grid.add_cell_button_color("", i, 1, 2, bg='#%02X%02X%02X' % (r(23, 212), r(50, 214), r(0, 255)))
self.__grid.add_cell_label("", i, 2, 2)
row = 0
self.__configs = []
for config in configs:
Tk.Label(self.__dialog, text=config.title()).grid(row=row, padx=4, pady=4, sticky=Tk.W)
entry = Tk.Entry(self.__dialog)
entry.insert(0, str(configs[config].value))
entry.grid(row=row, column=1, padx=4, pady=4, sticky=Tk.W)
if row == 0:
entry.focus_set()
self.__configs.append( TkConfig.TkConfig(config, configs[config].value, c_type=configs[config].c_type, tk_entry=entry) )
row += 1
B1 = Tk.Button(self.__dialog, text="Ok", width=5, command = lambda *_: self.__apply( callback ))
B1.grid(row=row, padx=6, pady=6, sticky=Tk.W)
self.__grid.pack(side=Tk.LEFT, fill=Tk.Y, expand=False)
self.__dialog.bind("<Return>", lambda *_: self.__apply( callback ))
def clear_panel_classes(self):
for i in range(1, 20):
self.__grid.add_cell_label("", i, 0, 12)
self.__grid.add_cell_label("", i, 1, 2)
def close_panel(self):
if self.__grid is not None:
self.__grid.pack_forget();
self.__grid.destroy();
B2 = Tk.Button(self.__dialog, text="Cancel", width=5, command = self.__dialog.destroy)
B2.grid(row=row, column=1, padx=6, pady=6, sticky=Tk.W)
self.__dialog.bind("<Escape>", lambda *_: self.__dialog.destroy())
def popup(self):
pass
self.__dialog.grab_set()
self.__dialog.protocol("WM_DELETE_WINDOW", self.__dialog.destroy)
self.__dialog.geometry("+%d+%d" % (self.__root.winfo_width()/3,
self.__root.winfo_height()/3))
def log_and_popup(self, message):
pass
def dialogue_config(self, title, configs, callback):
self.__conf_dialog = TkCustomDialog.ConfigDialog(self.__root, title, configs, command_ok = lambda *_: self.__apply( callback ))
def get_config_and_destroy(self):
if self.__conf_dialog is None:
return None
try:
configs = {}
for config in self.__configs:
for config in self.__conf_dialog.get_configs():
config.value = config.get_entry_val()
configs[config.label] = config
except:
self.__dialog.destroy()
self.__conf_dialog.destroy()
raise IException("Illegal values, please try again")
self.__dialog.destroy()
self.__conf_dialog.destroy()
self.__conf_dialog = None
return configs
def show_error(self, fmt, *args):
tkMessageBox.showerror("Error", fmt % args)
def show_info(self, fmt, *args):
tkMessageBox.showinfo("Info", fmt % args)
def show_warning(self, fmt, *args):
tkMessageBox.showwarning("Warning", fmt % args)
def show(self):
self.__root.protocol("WM_DELETE_WINDOW", self.quit)
self.__root.mainloop()
def quit(self):
if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
......@@ -249,6 +209,6 @@ class TkInterface(Interface):
if warning == True:
self.show_warning( message )
elif IException.DEBUG == True:
self.append_logger( message )
self.append_log( message )
else:
self.show_error( message )
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Nome: TkCanvas.py
Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
Descricão: TODO
"""
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib import pylab as plt
class Image(object):
parent = None
__im = None
__canvas = None
def __init__(self, parent, image, onclick = None):
self.parent = parent
self.parent.image = image
fig = plt.figure(facecolor='white')
self.__im = plt.imshow(self.parent.image) # later use a.set_data(new_data)
#ax = plt.gca()
#ax.set_xticklabels([])
#ax.set_yticklabels([])
# a tk.DrawingArea
self.__canvas = FigureCanvasTkAgg(fig, master=self.parent)
self.__canvas.show()
self.__canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
if onclick is not None:
fig.canvas.mpl_connect('button_press_event', func = onclick)
def refresh(self, image):
if self.__canvas is not None:
self.parent.image = image
self.__im.set_data(self.parent.image)
self.__canvas.draw()
def close(self):
if self.__canvas is not None:
self.parent.image = None
#self.__im.set_data(np.zeros((0,0,3), float))
#self.__canvas.draw()
self.__canvas.get_tk_widget().pack_forget();
self.__canvas.get_tk_widget().destroy();
self.__im = None
self.__canvas = None
return True
return False
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Nome: TkCustomDialog.py
Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
Descricão: Classe que customiza as janelas de dialogo da biblioteca TkInter.
"""
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
from TkConfig import TkConfig
class ConfigDialog(Tk.Toplevel):
parent = None
__configs = None
def __init__(self, parent, title = None, configs = None, command_ok = None):
self.parent = parent
Tk.Toplevel.__init__(self, self.parent, padx=10, pady=10)
self.transient(self.parent)
if title is not None:
self.title(title)
self.grab_set()
if configs is not None:
self.add_configs(configs, command_ok)
self.geometry("+%d+%d" % (parent.winfo_width()/3,
parent.winfo_height()/3))
self.protocol("WM_DELETE_WINDOW", self.destroy)
def add_configs(self, configs, command_ok):
row = 0
self.__configs = []
for config in configs:
Tk.Label(self, text=config.title()).grid(row=row, padx=4, pady=4, sticky=Tk.W)
entry = Tk.Entry(self)
entry.insert(0, str(configs[config].value))
entry.grid(row=row, column=1, padx=4, pady=4, sticky=Tk.W)
if row == 0:
entry.focus_set()
self.__configs.append( TkConfig(config, configs[config].value, c_type=configs[config].c_type, tk_entry=entry) )
row += 1
B1 = Tk.Button(self, text="Ok", width=5, command = command_ok)
B1.grid(row=row, padx=6, pady=6, sticky=Tk.W)
self.bind("<Return>", command_ok)
B2 = Tk.Button(self, text="Cancel", width=5, command = self.destroy)
B2.grid(row=row, column=1, padx=6, pady=6, sticky=Tk.W)
self.bind("<Escape>", lambda *_: self.destroy())
def get_configs(self):
return self.__configs
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Nome: TkCustomFrame.py
Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
Descricão: TODO.
"""
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
from TkUtils import Utils
class CustomGrid(Tk.Frame):
parent = None
v = None
def __init__(self, parent, width = 0, height = 0, bg='white'):
self.parent = parent
self.v = Tk.IntVar()
Tk.Frame.__init__(self, self.parent, width=width, height=height, bg=bg)
def add_cell_label(self, text, row, column, width=0, height=0, bg='white', fg="black"):
Tk.Label(self, text=text, width=width, height=height, bg=bg, fg=fg, padx=4, pady=4).grid(row=row, column=column)
def add_cell_button_color(self, text, row, column, width=0, height=0, bg='white', fg="black", command=None):
Tk.Button(self, text=text, width=width, height=height, bg=bg, fg=fg, padx=0, pady=0,
command = lambda *_: Utils.ask_color_choose(default_color = bg)).grid(row=row, column=column)
def add_cell_radio_button(self, text, value, row, column, width=0, height=0, bg='white', fg="black", selected=False, command=None):
radio = Tk.Radiobutton(self, text=text, variable=self.v, value=value,
width=width, height=height, bg=bg, fg=fg, padx=4, pady=4,
indicatoron=1,
activebackground='#404040', highlightbackground='white')
radio.grid(row=row, column=column)
if(selected == True):
radio.select()
......@@ -13,23 +13,25 @@ from abc import ABCMeta, abstractmethod
class ItemMenu(object):
__metaclass__ = ABCMeta
parent = None
shortcut = None