Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
inovisao
pynovisao
Commits
26e0252b
Commit
26e0252b
authored
Aug 26, 2016
by
Alessandro dos Santos Ferreira
Browse files
Pynovisao - Configuracao de classes
parent
75eca498
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
600 additions
and
187 deletions
+600
-187
README.md
README.md
+1
-1
src/Pynovisao.py
src/Pynovisao.py
+159
-0
src/actions.py
src/actions.py
+0
-124
src/interface/TkInterface.py
src/interface/TkInterface.py
+43
-26
src/interface/tk/TkCanvas.py
src/interface/tk/TkCanvas.py
+1
-1
src/interface/tk/TkConfig.py
src/interface/tk/TkConfig.py
+5
-4
src/interface/tk/TkCustomDialog.py
src/interface/tk/TkCustomDialog.py
+33
-19
src/interface/tk/TkCustomFrame.py
src/interface/tk/TkCustomFrame.py
+9
-4
src/interface/tk/TkItemMenu.py
src/interface/tk/TkItemMenu.py
+29
-0
src/interface/tk/TkMenu.py
src/interface/tk/TkMenu.py
+3
-0
src/main.py
src/main.py
+55
-0
src/segmentation/Slic.py
src/segmentation/Slic.py
+6
-6
src/util/Config.py
src/util/Config.py
+10
-1
src/util/Utils.py
src/util/Utils.py
+10
-0
src/util/X11Colors.py
src/util/X11Colors.py
+235
-0
src/util/__init__.py
src/util/__init__.py
+1
-1
No files found.
README.md
View file @
26e0252b
...
...
@@ -15,7 +15,7 @@ Pacote de Visão Computacional do Inovisão.
```
```
$ python
pynovisao
.py
$ python
main
.py
```
...
...
src/Pynovisao.py
0 → 100644
View file @
26e0252b
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Nome: Pynovisao.py
Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
Descricão: TODO
"""
from
collections
import
OrderedDict
from
interface
import
*
from
interface.Interface
import
InterfaceException
as
IException
from
segmentation
import
*
from
util
import
*
from
util.Config
import
Config
from
util.File
import
File
as
f
class
Act
(
object
):
tk
=
None
segmenter
=
None
classes
=
None
__image
=
None
__const_image
=
None
__segments
=
None
def
__init__
(
self
,
tk
):
self
.
tk
=
tk
self
.
segmenter
=
Slic
.
Slic
()
self
.
classes
=
[]
self
.
add_class
(
dialog
=
False
,
color
=
'green'
)
self
.
add_class
(
dialog
=
False
,
color
=
'yellow'
)
def
open_image
(
self
):
def
onclick
(
event
):
if
event
.
xdata
!=
None
and
event
.
ydata
!=
None
and
int
(
event
.
ydata
)
!=
0
:
x
=
int
(
event
.
xdata
)
y
=
int
(
event
.
ydata
)
self
.
tk
.
write_log
(
"Coordinates: x = %d y = %d "
,
x
,
y
)
if
self
.
__segments
is
not
None
:
self
.
tk
.
append_log
(
"Segment = %d"
,
segments
[
y
,
x
])
imagename
=
self
.
tk
.
utils
.
ask_image_name
()
if
imagename
:
self
.
__image
=
f
.
open_image
(
imagename
)
name
=
f
.
get_filename
(
imagename
)
self
.
tk
.
write_log
(
"Opening %s..."
,
name
)
self
.
tk
.
add_image
(
self
.
__image
,
name
,
onclick
)
self
.
__const_image
=
self
.
__image
def
rotate_image
(
self
):
if
self
.
__const_image
is
None
:
raise
IException
(
"Image not found"
)
image
=
self
.
f
.
rotate_image
(
self
.
__const_image
)
self
.
tk
.
write_log
(
"Rotating image 90 degrees"
)
self
.
tk
.
refresh_image
(
self
.
__image
)
self
.
__const_image
=
self
.
__image
def
close_image
(
self
):
if
self
.
__const_image
is
None
:
raise
IException
(
"Image not found"
)
if
self
.
tk
.
close_image
():
self
.
tk
.
write_log
(
"Closing image..."
)
self
.
__const_image
=
None
self
.
__segments
=
None
def
add_class
(
self
,
dialog
=
True
,
color
=
None
):
n_classes
=
len
(
self
.
classes
)
if
n_classes
>=
self
.
tk
.
MAX_CLASSES
:
raise
IException
(
"You have reached the limite of %d classes"
%
self
.
tk
.
MAX_CLASSES
)
def
edit_class
(
index
):
self
.
edit_class
(
index
)
def
process_config
():
new_class
=
self
.
tk
.
get_config_and_destroy
()
self
.
classes
.
append
(
new_class
)
self
.
tk
.
write_log
(
"New class: %s"
,
new_class
[
"name"
].
value
)
self
.
tk
.
refresh_panel_classes
(
self
.
classes
)
if
color
is
None
:
color
=
X11Colors
.
Colors
.
random_color
()
class_config
=
OrderedDict
()
class_config
[
"name"
]
=
Config
(
label
=
"Name"
,
value
=
"Class %02d"
%
(
n_classes
+
1
),
c_type
=
str
)
class_config
[
"color"
]
=
Config
(
label
=
"Color (X11 Colors)"
,
value
=
color
,
c_type
=
'color'
)
class_config
[
"callback"
]
=
Config
(
label
=
None
,
value
=
edit_class
,
c_type
=
None
,
hidden
=
True
)
class_config
[
"args"
]
=
Config
(
label
=
None
,
value
=
n_classes
,
c_type
=
int
,
hidden
=
True
)
if
dialog
==
False
:
self
.
classes
.
append
(
class_config
)
return
title
=
"Add a new classe"
self
.
tk
.
dialogue_config
(
title
,
class_config
,
process_config
)
def
edit_class
(
self
,
index
):
def
process_update
(
index
):
updated_class
=
self
.
tk
.
get_config_and_destroy
()
self
.
classes
[
index
]
=
updated_class
self
.
tk
.
write_log
(
"Class updated: %s"
,
updated_class
[
"name"
].
value
)
self
.
tk
.
refresh_panel_classes
(
self
.
classes
)
current_config
=
self
.
classes
[
index
]
title
=
"Edit class %s"
%
current_config
[
"name"
].
value
self
.
tk
.
dialogue_config
(
title
,
current_config
,
lambda
*
_
:
process_update
(
index
))
def
run_segmentation
(
self
):
if
self
.
__const_image
is
None
:
raise
IException
(
"Image not found"
)
self
.
tk
.
write_log
(
"Running %s,,,"
,
self
.
segmenter
.
get_name
())
self
.
tk
.
append_log
(
"
\n
Config: %s"
,
str
(
self
.
segmenter
.
get_summary_config
()))
self
.
__segments
,
self
.
__image
,
run_time
=
self
.
segmenter
.
run
(
self
.
__const_image
)
self
.
tk
.
append_log
(
"
\n
Time elapsed: %0.3f seconds"
,
run_time
)
self
.
tk
.
refresh_image
(
self
.
__image
)
def
config_segmentation
(
self
):
title
=
"Configuring %s"
%
self
.
segmenter
.
get_name
()
self
.
tk
.
write_log
(
title
)
current_config
=
self
.
segmenter
.
get_config
()
def
process_config
():
new_config
=
self
.
tk
.
get_config_and_destroy
()
self
.
segmenter
.
set_config
(
new_config
)
self
.
tk
.
append_log
(
"
\n
Config updated: %s"
,
str
(
self
.
segmenter
.
get_summary_config
()))
self
.
tk
.
dialogue_config
(
title
,
current_config
,
process_config
)
def
func_not_available
(
self
):
self
.
tk
.
write_log
(
"This functionality is not available right now."
)
src/actions.py
deleted
100644 → 0
View file @
75eca498
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
"""
Nome: actions.py
Autor: Alessandro dos Santos Ferreira ( santosferreira.alessandro@gmail.com )
Descricão: TODO
"""
import
sys
import
traceback
from
interface
import
*
from
segmentation
import
*
from
util
import
*
DEBUG
=
True
IException
=
Interface
.
InterfaceException
f
=
File
.
File
segmenter
=
Slic
.
Slic
()
image
=
None
const_image
=
None
segments
=
None
def
open_image
(
tk
):
global
image
,
const_image
def
onclick
(
event
):
if
event
.
xdata
!=
None
and
event
.
ydata
!=
None
and
int
(
event
.
ydata
)
!=
0
:
x
=
int
(
event
.
xdata
)
y
=
int
(
event
.
ydata
)
tk
.
write_log
(
"Coordinates: x = %d y = %d "
,
x
,
y
)
if
segments
is
not
None
:
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_log
(
"Opening %s..."
,
name
)
tk
.
add_image
(
image
,
name
,
onclick
)
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
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
if
const_image
is
None
:
raise
IException
(
"Image not found"
)
if
tk
.
close_image
():
tk
.
write_log
(
"Closing image..."
)
const_image
=
None
segments
=
None
def
run_segmentation
(
tk
):
global
image
,
const_image
,
segments
if
const_image
is
None
:
raise
IException
(
"Image not found"
)
tk
.
write_log
(
"Running %s,,,"
,
segmenter
.
get_name
())
tk
.
append_log
(
"
\n
Config: %s"
,
str
(
segmenter
.
get_summary_config
()))
segments
,
image
,
run_time
=
segmenter
.
run
(
const_image
)
tk
.
append_log
(
"
\n
Time elapsed: %0.3f seconds"
,
run_time
)
tk
.
refresh_image
(
image
)
def
config_segmentation
(
tk
):
global
segmenter
title
=
"Configuring %s"
%
segmenter
.
get_name
()
tk
.
write_log
(
title
)
current_config
=
segmenter
.
get_config
()
def
process_config
():
new_config
=
tk
.
get_config_and_destroy
()
segmenter
.
set_config
(
new_config
)
tk
.
append_log
(
"
\n
Config 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_log
(
"This functionality is not available right now."
)
src/interface/TkInterface.py
View file @
26e0252b
...
...
@@ -19,6 +19,8 @@ from tk import *
class
TkInterface
(
Interface
):
MAX_CLASSES
=
20
utils
=
TkUtils
.
Utils
title
=
None
...
...
@@ -27,6 +29,7 @@ class TkInterface(Interface):
__menus
=
None
__image
=
None
__grid
=
None
__logger
=
None
def
__init__
(
self
,
title
):
...
...
@@ -37,7 +40,6 @@ class TkInterface(Interface):
self
.
__root
.
geometry
(
'%dx%d+%d+%d'
%
(
800
,
600
,
0
,
0
))
self
.
__menus
=
[]
self
.
__configs
=
[]
def
set_subtitle
(
self
,
subtitle
):
self
.
__root
.
wm_title
(
self
.
title
+
' - '
+
subtitle
)
...
...
@@ -51,6 +53,9 @@ class TkInterface(Interface):
def
add_separator
(
self
):
self
.
__menus
[
-
1
].
add_separator
(
)
def
add_check_button
(
self
,
label
,
action
,
shortcut
=
None
):
self
.
__menus
[
-
1
].
add_check_button
(
label
=
label
,
action
=
lambda
*
_
:
self
.
__apply
(
action
),
shortcut
=
shortcut
)
def
render_menu
(
self
):
menubar
=
Tk
.
Menu
(
self
.
__root
)
...
...
@@ -62,10 +67,10 @@ class TkInterface(Interface):
def
add_image
(
self
,
image
,
title
=
None
,
onclick
=
None
):
if
self
.
__image
is
None
:
self
.
__image
=
TkCanvas
.
Image
(
self
.
__root
,
image
,
lambda
event
,
*
_
:
self
.
__apply
(
onclick
,
event
)
)
else
:
self
.
__image
.
refresh
(
image
)
if
self
.
__image
is
not
None
:
self
.
__image
.
close
(
)
self
.
__image
=
TkCanvas
.
Image
(
self
.
__root
,
image
,
lambda
event
,
*
_
:
self
.
__apply
(
onclick
,
event
)
)
if
title
is
not
None
:
self
.
set_subtitle
(
title
)
...
...
@@ -103,10 +108,17 @@ class TkInterface(Interface):
def
clear_log
(
self
):
if
self
.
__logger
:
self
.
__logger
.
clear_logger
()
def
toogle_log
(
self
):
if
self
.
__logger
:
self
.
close_log
()
else
:
self
.
open_log
()
def
close_log
(
self
):
if
self
.
__logger
:
self
.
__logger
.
destroy_logger
()
self
.
__logger
=
None
def
add_panel
(
self
,
left
=
True
):
...
...
@@ -118,24 +130,30 @@ class TkInterface(Interface):
def
add_panel_classes
(
self
,
classes
=
None
):
if
self
.
__grid
is
None
:
self
.
__grid
=
TkCustomFrame
.
CustomGrid
(
self
.
__root
)
else
:
self
.
clear_panel_classes
()
from
random
import
randint
as
r
length
=
r
(
2
,
16
)
self
.
__grid
.
add_cell_label
(
"Classes "
,
0
,
0
,
12
,
4
)
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
)
classes
=
classes
if
classes
is
not
None
else
[]
self
.
__grid
.
add_cell_label
(
""
,
0
,
0
,
1
,
4
)
self
.
__grid
.
add_cell_label
(
"Classes "
,
0
,
1
,
12
,
4
)
self
.
__grid
.
add_cell_label
(
""
,
0
,
3
,
2
,
4
)
length
=
len
(
classes
)
for
i
in
range
(
1
,
length
+
1
):
self
.
__grid
.
add_cell_radio_button
(
classes
[
i
-
1
][
"name"
].
value
[:
12
],
i
,
i
,
1
,
12
,
selected
=
False
if
i
>
1
else
True
)
self
.
__grid
.
add_cell_button_color
(
""
,
i
,
2
,
2
,
bg
=
classes
[
i
-
1
][
"color"
].
value
,
command
=
classes
[
i
-
1
][
"callback"
].
value
,
command_args
=
classes
[
i
-
1
][
"args"
].
value
)
self
.
__grid
.
pack
(
side
=
Tk
.
LEFT
,
fill
=
Tk
.
Y
,
expand
=
False
)
def
refresh_panel_classes
(
self
,
classes
=
None
):
self
.
clear_panel_classes
()
self
.
add_panel_classes
(
classes
)
def
clear_panel_classes
(
self
):
for
i
in
range
(
1
,
20
):
self
.
__grid
.
add_cell_label
(
""
,
i
,
0
,
1
2
)
self
.
__grid
.
add_cell_label
(
""
,
i
,
1
,
2
)
for
i
in
range
(
1
,
self
.
MAX_CLASSES
+
1
):
self
.
__grid
.
add_cell_label
(
""
,
i
,
1
,
1
5
)
self
.
__grid
.
add_cell_label
(
""
,
i
,
2
,
2
)
def
close_panel
(
self
):
if
self
.
__grid
is
not
None
:
...
...
@@ -158,18 +176,17 @@ class TkInterface(Interface):
return
None
try
:
configs
=
{}
for
config
in
self
.
__conf_dialog
.
get_configs
():
config
.
value
=
config
.
get_entry_val
()
configs
[
config
.
label
]
=
config
self
.
__conf_dialog
.
update_and_validate_configs
()
configs
=
self
.
__conf_dialog
.
get_configs
()
self
.
__conf_dialog
.
destroy
()
self
.
__conf_dialog
=
None
return
configs
except
:
self
.
__conf_dialog
.
destroy
()
raise
IException
(
"Illegal values, please try again"
)
self
.
__conf_dialog
.
destroy
()
self
.
__conf_dialog
=
None
return
configs
def
show_error
(
self
,
fmt
,
*
args
):
...
...
src/interface/tk/TkCanvas.py
View file @
26e0252b
...
...
@@ -32,7 +32,7 @@ class Image(object):
self
.
parent
.
image
=
image
fig
=
plt
.
figure
(
facecolor
=
'white'
)
fig
=
plt
.
figure
(
facecolor
=
'white'
,
edgecolor
=
'black'
,
linewidth
=
1
)
self
.
__im
=
plt
.
imshow
(
self
.
parent
.
image
)
# later use a.set_data(new_data)
#ax = plt.gca()
#ax.set_xticklabels([])
...
...
src/interface/tk/TkConfig.py
View file @
26e0252b
...
...
@@ -14,10 +14,11 @@ class TkConfig(Config):
tk_entry
=
None
def
__init__
(
self
,
label
,
value
,
c_type
,
tk_entry
,
min_value
=
None
,
max_value
=
None
):
super
(
self
.
__class__
,
self
).
__init__
(
label
,
value
,
c_type
,
min_value
,
max_value
)
def
__init__
(
self
,
label
,
value
,
c_type
,
tk_entry
=
None
,
hidden
=
False
,
min_value
=
None
,
max_value
=
None
):
super
(
self
.
__class__
,
self
).
__init__
(
label
,
value
,
c_type
,
hidden
,
min_value
,
max_value
)
self
.
tk_entry
=
tk_entry
def
get_entry_val
(
self
):
return
(
self
.
c_type
)(
self
.
tk_entry
.
get
())
if
self
.
tk_entry
is
not
None
:
self
.
value
=
self
.
tk_entry
.
get
()
return
self
.
get_cast_val
()
src/interface/tk/TkCustomDialog.py
View file @
26e0252b
...
...
@@ -13,15 +13,15 @@ if sys.version_info[0] < 3:
else
:
import
tkinter
as
Tk
from
collections
import
OrderedDict
from
TkConfig
import
TkConfig
class
Config
Dialog
(
Tk
.
Toplevel
):
class
Simple
Dialog
(
Tk
.
Toplevel
):
parent
=
None
__configs
=
None
def
__init__
(
self
,
parent
,
title
=
None
,
configs
=
None
,
command_ok
=
None
):
def
__init__
(
self
,
parent
,
title
=
None
,
command_ok
=
None
):
self
.
parent
=
parent
Tk
.
Toplevel
.
__init__
(
self
,
self
.
parent
,
padx
=
10
,
pady
=
10
)
...
...
@@ -32,29 +32,40 @@ class ConfigDialog(Tk.Toplevel):
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
)
class
ConfigDialog
(
SimpleDialog
):
__configs
=
None
def
__init__
(
self
,
parent
,
title
=
None
,
configs
=
None
,
command_ok
=
None
):
SimpleDialog
.
__init__
(
self
,
parent
,
title
,
command_ok
)
if
configs
is
not
None
:
self
.
add_configs
(
configs
,
command_ok
)
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
=
OrderedDict
()
for
key
in
configs
:
if
configs
[
key
].
hidden
==
False
:
Tk
.
Label
(
self
,
text
=
configs
[
key
].
label
).
grid
(
row
=
row
,
padx
=
4
,
pady
=
4
,
sticky
=
Tk
.
W
)
entry
=
Tk
.
Entry
(
self
)
entry
.
insert
(
0
,
str
(
configs
[
key
].
value
))
entry
.
grid
(
row
=
row
,
column
=
1
,
padx
=
4
,
pady
=
4
,
sticky
=
Tk
.
W
)
if
row
==
0
:
entry
.
focus_set
()
row
+=
1
self
.
__configs
.
append
(
TkConfig
(
config
,
configs
[
config
].
value
,
c_type
=
configs
[
config
].
c_type
,
tk_entry
=
entry
)
)
row
+=
1
self
.
__configs
[
key
]
=
TkConfig
(
configs
[
key
].
label
,
configs
[
key
].
value
,
c_type
=
configs
[
key
].
c_type
,
tk_entry
=
entry
,
hidden
=
configs
[
key
].
hidden
)
else
:
self
.
__configs
[
key
]
=
TkConfig
(
configs
[
key
].
label
,
configs
[
key
].
value
,
c_type
=
configs
[
key
].
c_type
,
hidden
=
configs
[
key
].
hidden
)
B1
=
Tk
.
Button
(
self
,
text
=
"Ok"
,
width
=
5
,
command
=
command_ok
)
B1
.
grid
(
row
=
row
,
padx
=
6
,
pady
=
6
,
sticky
=
Tk
.
W
)
...
...
@@ -67,6 +78,9 @@ class ConfigDialog(Tk.Toplevel):
self
.
bind
(
"<Escape>"
,
lambda
*
_
:
self
.
destroy
())
def
update_and_validate_configs
(
self
):
for
key
in
self
.
__configs
:
self
.
__configs
[
key
].
value
=
self
.
__configs
[
key
].
get_entry_val
()
def
get_configs
(
self
):
return
self
.
__configs
src/interface/tk/TkCustomFrame.py
View file @
26e0252b
...
...
@@ -14,6 +14,8 @@ else:
import
tkinter
as
Tk
from
TkUtils
import
Utils
from
util.X11Colors
import
Colors
class
CustomGrid
(
Tk
.
Frame
):
parent
=
None
...
...
@@ -32,16 +34,19 @@ class CustomGrid(Tk.Frame):
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
):
def
add_cell_button_color
(
self
,
text
,
row
,
column
,
width
=
0
,
height
=
0
,
bg
=
'white'
,
fg
=
"black"
,
command
=
None
,
command_args
=
None
):
bg_color
=
Colors
.
get_color_hex
(
bg
)
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
)
bt
=
Tk
.
Button
(
self
,
text
=
text
,
width
=
width
,
height
=
height
,
bg
=
bg_color
,
fg
=
fg
,
padx
=
0
,
pady
=
0
,
cursor
=
"hand1"
,
command
=
lambda
*
_
:
command
(
command_args
))
bt
.
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
,
indicatoron
=
1
,
anchor
=
Tk
.
W
,
activebackground
=
'#404040'
,
highlightbackground
=
'white'
)
radio
.
grid
(
row
=
row
,
column
=
column
)
...
...
src/interface/tk/TkItemMenu.py
View file @
26e0252b
...
...
@@ -7,6 +7,11 @@
Descricão: TODO
"""
import
sys
if
sys
.
version_info
[
0
]
<
3
:
import
Tkinter
as
Tk
else
:
import
tkinter
as
Tk
from
abc
import
ABCMeta
,
abstractmethod
...
...
@@ -51,3 +56,27 @@ class Separator(ItemMenu):
def
render
(
self
,
menu
):
menu
.
add_separator
()
class
CheckButton
(
ItemMenu
):
label
=
None
default_state
=
None
def
__init__
(
self
,
parent
,
label
,
action
,
shortcut
=
None
,
default_state
=
True
):
super
(
self
.
__class__
,
self
).
__init__
(
parent
)
self
.
label
=
label
self
.
action
=
action
if
shortcut
is
not
None
:
self
.
shortcut
=
str
(
shortcut
).
upper
()
self
.
default_state
=
default_state
<