Commit ba89e7f9 authored by André Anjos's avatar André Anjos 💬

[widgets] Make a reusable widget for the help message

parent 6f3e87c2
Pipeline #26527 passed with stages
in 12 minutes and 47 seconds
......@@ -145,61 +145,6 @@ import logging
logger = logging.getLogger(__name__)
class HelpDialog(tkinter.Toplevel):
def __init__(self, parent, message, canvas):
super(HelpDialog, self).__init__(parent)
self.transient(parent)
self.title('Help')
self.parent = parent
self.result = None
body = tkinter.Frame(self, width=200, height=400)
# Now build the dialog geometry
buttonbox = tkinter.Frame(body, height=20)
buttonbox.pack(side=tkinter.BOTTOM)
w = tkinter.Button(buttonbox, text="Dismiss", command=self.on_dismiss,
default=tkinter.ACTIVE)
w.pack(side=tkinter.RIGHT)
self.bind("<Return>", self.on_dismiss)
self.bind("<Escape>", self.on_dismiss)
textbox = tkinter.Frame(body, height=380)
textbox.pack(side=tkinter.TOP)
self.initial_focus = t = tkinter.Text(textbox)
t.insert(tkinter.INSERT, message) #fill in contents
scrollbar = tkinter.Scrollbar(textbox)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
t.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=t.yview)
t.config(state=tkinter.DISABLED)
t.pack(side=tkinter.TOP)
body.pack(padx=5, pady=5)
self.grab_set()
if not self.initial_focus: self.initial_focus = self
self.protocol("WM_DELETE_WINDOW", self.on_dismiss)
self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
parent.winfo_rooty()+50))
self.initial_focus.focus_set()
self.wait_window(self)
def on_dismiss(self, event=None):
# put focus back to the parent window
self.parent.focus_set()
self.destroy()
class AnnotatorApp(tkinter.Tk):
"""A wrapper for the annotation application
......@@ -268,16 +213,13 @@ class AnnotatorApp(tkinter.Tk):
self.tooltips = {}
self.canvas = None #where the image will be displayed
# expansion trick for grid layouts
_grid_expand = tkinter.S + tkinter.N + tkinter.W + tkinter.E
f = self.frames['left'] = tkinter.Frame(self)
f.pack(side=tkinter.LEFT, padx=5, pady=5, fill=tkinter.Y, expand=False)
# creates a little panel for information and buttons, on the left
f = self.frames['image-selector'] = tkinter.LabelFrame(f, text="Images",
padx=5, pady=5, font=self.font)
f.grid(row=0, sticky=_grid_expand)
f.grid(row=0, sticky=tkinter.NSEW)
v = self.variables['image-progress'] = tkinter.StringVar()
v.set('[progress]')
......@@ -287,19 +229,19 @@ class AnnotatorApp(tkinter.Tk):
b = self.buttons['previous-frame'] = tkinter.Button(f, text="<< (p)",
command=self.previous_frame, font=self.font)
b.grid(row=1, column=0, sticky=_grid_expand)
b.grid(row=1, column=0, sticky=tkinter.NSEW)
self.tooltips['previous-frame'] = \
widgets.Tooltip(b, text='Go to previous image (keyboard: p)')
b = self.buttons['next-frame'] = tkinter.Button(f, text=">> (n)",
command=self.next_frame, font=self.font)
b.grid(row=1, column=1, sticky=_grid_expand)
b.grid(row=1, column=1, sticky=tkinter.NSEW)
self.tooltips['next-frame'] = \
widgets.Tooltip(b, text='Go to next image (keyboard: n)')
f = self.frames['annotations'] = tkinter.LabelFrame(self.frames['left'],
text="Objects", padx=5, pady=5, font=self.font)
f.grid(row=1, sticky=_grid_expand)
f.grid(row=1, sticky=tkinter.NSEW)
v = self.variables['annotation-progress'] = tkinter.StringVar()
v.set('[progress]')
......@@ -310,25 +252,25 @@ class AnnotatorApp(tkinter.Tk):
b = self.buttons['previous-annotation'] = \
tkinter.Button(f, text="<< (O)", font=self.font,
command=self.activate_previous_annotation)
b.grid(row=1, column=0, sticky=_grid_expand)
b.grid(row=1, column=0, sticky=tkinter.NSEW)
self.tooltips['previous-annotation'] = widgets.Tooltip(b,
text='Highlight (edit) previous object (keyboard: O)')
b = self.buttons['next-annotation'] = tkinter.Button(f, font=self.font,
text=">> (o)", command=self.activate_next_annotation)
b.grid(row=1, column=1, sticky=_grid_expand)
b.grid(row=1, column=1, sticky=tkinter.NSEW)
self.tooltips['next-annotation'] = widgets.Tooltip(b,
text='Highlight (edit) next object (keyboard: o)')
b = self.buttons['create-object'] = tkinter.Button(f, font=self.font,
text="new (c)", command=self.create_new_annotation)
b.grid(row=2, column=0, sticky=_grid_expand)
b.grid(row=2, column=0, sticky=tkinter.NSEW)
self.tooltips['create-object'] = widgets.Tooltip(b,
text='Annotate a new object (keyboard: c)')
b = self.buttons['delete-object'] = tkinter.Button(f, font=self.font,
text="del (D)", command=self.remove_active_annotation)
b.grid(row=2, column=1, sticky=_grid_expand)
b.grid(row=2, column=1, sticky=tkinter.NSEW)
self.tooltips['create-object'] = widgets.Tooltip(b,
text='Remove active object (keyboard: D)')
......@@ -337,7 +279,7 @@ class AnnotatorApp(tkinter.Tk):
b = self.buttons['toggle-mode'] = \
tkinter.Button(f, textvariable=v, font=self.font,
command=self.toggle_active_annotation_mode)
b.grid(row=3, columnspan=2, sticky=_grid_expand)
b.grid(row=3, columnspan=2, sticky=tkinter.NSEW)
self.tooltips['decoration-mode'] = widgets.Tooltip(b,
text='Toggle between ALT decoration modes. This is no way ' \
'affects annotation results (keyboard: m)')
......@@ -353,7 +295,7 @@ class AnnotatorApp(tkinter.Tk):
f = self.frames['filters'] = tkinter.LabelFrame(self.frames['left'],
text="Filters", padx=5, pady=5, font=self.font)
f.grid(row=2, sticky=_grid_expand)
f.grid(row=2, sticky=tkinter.NSEW)
b = self.buttons['adaheq'] = tkinter.Checkbutton(f,
text="CLAHE", command=self.toggle_filter, font=self.font)
......@@ -383,7 +325,7 @@ class AnnotatorApp(tkinter.Tk):
f = self.frames['pointer'] = tkinter.LabelFrame(self.frames['left'],
text="Pointer [x, y]", padx=5, pady=5, font=self.font)
f.grid(row=3, sticky=_grid_expand)
f.grid(row=3, sticky=tkinter.NSEW)
v = self.variables['pointer-position'] = tkinter.StringVar()
v.set('(0, 0)')
......@@ -397,7 +339,7 @@ class AnnotatorApp(tkinter.Tk):
f = self.frames['zoom'] = tkinter.LabelFrame(self.frames['left'],
text="Zoom", padx=5, pady=5, font=self.font)
f.grid(row=4, sticky=_grid_expand)
f.grid(row=4, sticky=tkinter.NSEW)
v = self.variables['zoom'] = tkinter.StringVar()
v.set('%g' % self.zoom)
......@@ -408,12 +350,12 @@ class AnnotatorApp(tkinter.Tk):
f = self.frames['help'] = tkinter.LabelFrame(self.frames['left'],
text="Help", padx=5, pady=5, font=self.font)
f.grid(row=5, sticky=_grid_expand)
f.grid(row=5, sticky=tkinter.NSEW)
b = self.buttons['display-help'] = \
tkinter.Button(f, text='help (?)', font=self.font,
command=self.on_help)
b.grid(row=0, sticky=_grid_expand)
b.grid(row=0, sticky=tkinter.NSEW)
self.tooltips['display-help'] = widgets.Tooltip(b,
text='Click on this button to display the help dialog and ' \
'learn more about keyboard and mouse-based shortcuts')
......@@ -584,7 +526,8 @@ class AnnotatorApp(tkinter.Tk):
def on_help(self, event=None):
"""Creates a help dialog box with the currently enabled commands"""
dialog = HelpDialog(self, __doc__, self.canvas)
self.withdraw()
dialog = widgets.HelpDialog(self, (600, 700), __doc__)
def previous_frame(self, event=None):
......
......@@ -851,3 +851,60 @@ class ImageCarousel(tkinter.Canvas):
"""Returns the number of images in the carousel"""
return len(self.filelist)
class Dialog(tkinter.Toplevel):
"""A pop-up window dialog - no internal objects"""
def __init__(self, parent, shape):
self.parent = parent
super(Dialog, self).__init__()
self.transient(self.parent)
# this is where the dialog will appear
self.geometry("%dx%d+%d+%d" % (shape[0], shape[1],
parent.winfo_rootx()+50, parent.winfo_rooty()+50))
self.lift()
# binds return, escape and window-close actions to `self.on_close()`
self.bind("<Return>", self.on_close)
self.bind("<Escape>", self.on_close)
self.protocol("WM_DELETE_WINDOW", self.on_close)
def on_close(self, event=None):
self.destroy()
self.parent.update()
self.parent.deiconify()
class HelpDialog(Dialog):
"""A pop-up specialization for the help message"""
def __init__(self, parent, shape, text):
super(HelpDialog, self).__init__(parent, shape)
self.title('Help')
# placeholder for the help text
tbox = tkinter.Text(self, width=50, height=70)
tbox.insert(tkinter.INSERT, text) #fill in contents
tbox.grid(row=0, column=0, sticky=tkinter.NSEW)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# scrollbar for the help text
scrollbar = tkinter.Scrollbar(tbox)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
tbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=tbox.yview)
tbox.config(state=tkinter.DISABLED)
# a single dismiss button
btn = tkinter.Button(self, text ="Dismiss", command=lambda: self.on_close())
btn.grid(row=1, column=0, sticky=tkinter.S)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment