Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Guillaume Sabbagh
Modification de categories
Commits
339eeee3
Commit
339eeee3
authored
Jun 25, 2021
by
Francois Mares
Browse files
upgrade OpenGl to NetworkX
parent
17ed6aff
Changes
12
Hide whitespace changes
Inline
Side-by-side
GUI/Model.py
View file @
339eeee3
...
...
@@ -131,7 +131,6 @@ class Model:
"""
def
exporterGraphviz
(
self
,
uids
):
data
=
self
.
getObject
(
uids
)
with
ThreadPoolExecutor
(
max_workers
=
len
(
data
))
as
executor
:
for
index
,
row
in
data
.
iterrows
():
obj
=
row
[
"object"
]
...
...
@@ -153,8 +152,7 @@ class Description:
return
self
.
_str
def
generer
(
self
):
mo
=
ModelObjects
.
get
(
self
.
_obj
)
if
mo
==
ModelObjects
.
GC
:
if
issubclass
(
type
(
self
.
_obj
),
Categorie
):
return
self
.
_genererDescriptionCategorie
()
else
:
return
str
(
self
.
_obj
)
...
...
@@ -165,15 +163,15 @@ class Description:
`limite_fleches` est le nombre maximal de flèches entre deux objets qu'on s'autorise à afficher.
"""
descr
=
""
if
self
.
_obj
.
nom
:
descr
+=
self
.
_obj
.
nom
# objets
descr
+=
" {"
print
(
self
)
for
o
in
self
.
_obj
.
objets
:
descr
+=
str
(
o
)
+
","
descr
=
descr
[:
-
1
]
+
"}"
if
(
len
(
self
.
_obj
.
objets
)
>
0
):
descr
=
descr
[:
-
1
]
+
"}"
else
:
descr
+=
"}"
# flesches
fleches_elem
=
set
(
self
.
_obj
[
self
.
_obj
.
objets
,
self
.
_obj
.
objets
])
...
...
@@ -211,11 +209,18 @@ class Description:
if
WARNING_LIMITE_FLECHES_ATTEINTE
:
print
(
"Warning : limite fleches entre "
+
str
(
source
)
+
" et "
+
str
(
cible
)
+
" atteinte."
)
break
descr
+=
" flèches: "
descr
+=
" {"
flag
=
False
for
f
in
fleches_non_elementaires
:
descr
+=
f
descr
+=
f
+
","
flag
=
True
for
f
in
fleches_elementaires
:
descr
+=
f
descr
+=
f
+
","
flag
=
True
if
flag
:
descr
=
descr
[:
-
1
]
+
"}"
else
:
descr
+=
"}"
return
descr
...
...
GUI/Parameters.py
View file @
339eeee3
...
...
@@ -4,20 +4,35 @@
class
Parameters
():
"""
///////////////////// TK
"""
# Frames
FRAME_BD
=
2
# Section frame
SECTION_COLOR
=
"#649BB4"
SECTION_RELIEF
=
"groove"
SECTION_FONT_SIZE
=
10
SECTION_FONT_WEIGHT
=
'bold'
SECTION_FONT_UNDERLINE
=
0
FRAME_BD
=
2
# Inform frame
INFORM_BG
=
'#C0C0C0'
INFORM_FG
=
'black'
# Export frame
ExportAsDialog_BG
=
'white'
HIGHLIGHTCOLOR_BUTTON
=
"#649BB4"
"""
///////////////////// NetworkX
"""
# Graph
NODE_COLOR
=
'#000000'
EDGE_ELEMENTARY_COLOR
=
'#000000'
EDGE_NO_ELEMENTARY_COLOR
=
'#0033FF'
parameters
=
Parameters
()
GUI/
tko
/AppOgl.py
→
GUI/
ogl
/AppOgl.py
View file @
339eeee3
...
...
@@ -3,9 +3,9 @@
from
tkinter
import
Tk
,
YES
,
BOTH
from
tko
.TkOglWin
import
TkOglWin
from
ogl
.TkOglWin
import
TkOglWin
from
oglWrap.ogl_hdr
import
GL_BLEND
,
GL_COLOR_BUFFER_BIT
,
GL_DEPTH_BUFFER_BIT
,
GL_DEPTH_TEST
,
\
from
ogl.
oglWrap.ogl_hdr
import
GL_BLEND
,
GL_COLOR_BUFFER_BIT
,
GL_DEPTH_BUFFER_BIT
,
GL_DEPTH_TEST
,
\
GL_MODELVIEW
,
GL_ONE_MINUS_SRC_ALPHA
,
GL_PROJECTION
,
GL_QUADS
,
GL_RENDERER
,
\
GL_SRC_ALPHA
,
GL_VENDOR
,
GL_VERSION
,
\
glBegin
,
glClear
,
glBlendFunc
,
glClearColor
,
\
...
...
GUI/ogl/ReadMe.txt
0 → 100644
View file @
339eeee3
/* in MainWindow */
from ogl.AppOgl import AppOgl
_glFrame=None
...
def _initFrames(self):
...
# OGL frame
self._glFrame=Frame(self._frame)
self._glFrame.grid(row=0, column=0, sticky="nesw")
self.initGLApp()
...
def initGLApp(self):
self._glApp=AppOgl(self._glFrame, width=320, height=200)
self._glApp.pack(expand = YES, fill=BOTH)
\ No newline at end of file
GUI/
tko
/TkOglWin.py
→
GUI/
ogl
/TkOglWin.py
View file @
339eeee3
...
...
@@ -10,14 +10,14 @@ from tkinter import Frame
import
sys
if
sys
.
platform
.
startswith
(
'win32'
):
from
oglWrap.win32_gdi
import
PFD_DRAW_TO_WINDOW
,
PFD_SUPPORT_OPENGL
,
PFD_DOUBLEBUFFER
,
PFD_TYPE_RGBA
,
\
from
ogl.
oglWrap.win32_gdi
import
PFD_DRAW_TO_WINDOW
,
PFD_SUPPORT_OPENGL
,
PFD_DOUBLEBUFFER
,
PFD_TYPE_RGBA
,
\
PixelFormatDescriptor
,
get_dc
,
choose_pixel_format
,
set_pixel_format
,
\
get_pixel_format
,
swap_buffers
from
oglWrap.ogl_hdr
import
wglCreateContext
,
wglMakeCurrent
from
ogl.
oglWrap.ogl_hdr
import
wglCreateContext
,
wglMakeCurrent
elif
sys
.
platform
.
startswith
(
'linux'
):
from
oglWrap.x11_gdi
import
X11_None
,
x_open_display
from
oglWrap.ogl_hdr
import
PGLint
,
GLX_RGBA
,
GLX_DEPTH_SIZE
,
GLX_DOUBLEBUFFER
,
GL_TRUE
,
\
from
ogl.
oglWrap.x11_gdi
import
X11_None
,
x_open_display
from
ogl.
oglWrap.ogl_hdr
import
PGLint
,
GLX_RGBA
,
GLX_DEPTH_SIZE
,
GLX_DOUBLEBUFFER
,
GL_TRUE
,
\
GLX_BLUE_SIZE
,
GLX_GREEN_SIZE
,
GLX_RED_SIZE
,
\
glXChooseVisual
,
glXCreateContext
,
glXMakeCurrent
,
glXSwapBuffers
...
...
GUI/oglWrap/ogl_hdr.py
→
GUI/
ogl/
oglWrap/ogl_hdr.py
View file @
339eeee3
File moved
GUI/oglWrap/win32_gdi.py
→
GUI/
ogl/
oglWrap/win32_gdi.py
View file @
339eeee3
File moved
GUI/oglWrap/x11_gdi.py
→
GUI/
ogl/
oglWrap/x11_gdi.py
View file @
339eeee3
File moved
GUI/plot/PlotFrame.py
0 → 100644
View file @
339eeee3
"""entry point for Tkinter Window with OpenGL]
"""
from
itertools
import
product
from
tkinter
import
TOP
,
X
,
YES
,
BOTH
,
\
Frame
,
Label
from
Categorie
import
Categorie
from
tk.Factory
import
*
from
Parameters
import
parameters
import
matplotlib.pyplot
as
plt
import
matplotlib
matplotlib
.
use
(
"TkAgg"
)
from
matplotlib.figure
import
Figure
from
matplotlib.backends.backend_tkagg
import
(
FigureCanvasTkAgg
,
NavigationToolbar2Tk
)
import
networkx
as
nx
class
PlotFrame
(
Frame
):
_controller
=
None
_plot
=
None
_canvas
=
None
def
__init__
(
self
,
parent
,
controller
,
*
args
,
**
kwargs
):
assert
controller
Frame
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_controller
=
controller
self
.
columnconfigure
(
0
,
weight
=
1
,
minsize
=
200
)
self
.
rowconfigure
(
0
,
minsize
=
20
)
self
.
rowconfigure
(
1
,
weight
=
1
,
minsize
=
100
)
self
.
_initFrame
()
def
_initFrame
(
self
):
factory
.
buildSectionLabel
(
self
,
"Visualisation NetworkX"
).
grid
(
row
=
0
,
column
=
0
,
sticky
=
"nwe"
)
G
=
nx
.
fast_gnp_random_graph
(
n
=
10
,
p
=
0.5
,
directed
=
True
)
# draw
f
=
Figure
(
figsize
=
(
5
,
5
),
dpi
=
100
)
self
.
_plot
=
f
.
add_subplot
(
111
)
self
.
_plot
.
cla
()
nx
.
draw_networkx
(
G
,
ax
=
self
.
_plot
,
pos
=
nx
.
random_layout
(
G
),
node_color
=
'r'
,
edge_color
=
'b'
)
self
.
_canvas
=
FigureCanvasTkAgg
(
f
,
master
=
self
)
self
.
_canvas
.
draw
()
toolbar
=
NavigationToolbar2Tk
(
self
.
_canvas
,
self
,
pack_toolbar
=
False
)
toolbar
.
update
()
toolbar
.
grid
(
row
=
2
,
column
=
0
,
sticky
=
"nswe"
)
self
.
_canvas
.
get_tk_widget
().
grid
(
row
=
1
,
column
=
0
,
sticky
=
"nswe"
)
def
setGraph
(
self
,
graph
:
nx
.
Graph
):
self
.
_plot
.
cla
()
if
callable
(
getattr
(
graph
,
"check_planarity"
,
None
))
and
graph
.
check_planarity
()[
0
]:
nx
.
draw_networkx
(
graph
,
ax
=
self
.
_plot
,
pos
=
nx
.
planar_layout
(
graph
))
else
:
nx
.
draw_networkx
(
graph
,
ax
=
self
.
_plot
,
pos
=
nx
.
random_layout
(
graph
))
self
.
_canvas
.
draw
()
class
GraphGenerator
:
"""
Static
Construit le nx.Graph associé à un objet par la fonction 'give(object)'
"""
def
give
(
obj
)
->
nx
.
Graph
:
if
issubclass
(
type
(
obj
),
Categorie
):
return
GraphGenerator
.
_genererGrapheCategorie
(
obj
)
else
:
print
(
f
"Impossible de générer le graphe de l'objet:
{
obj
}
"
)
"""
GENERATEURS PAR CLASSE
"""
def
_genererGrapheCategorie
(
cat
,
afficher_identites
:
bool
=
True
,
complet
:
bool
=
True
,
limite_fleches
:
int
=
30
)
->
nx
.
Graph
:
"""
@param complet: - si True affiche toutes les flèches;
- si False affiche seulement les flèches élémentaires.
@param limite_fleches: nombre maximal de flèches entre deux objets.
"""
G
=
nx
.
MultiDiGraph
()
G
.
add_nodes_from
(
cat
.
objets
,
color
=
parameters
.
NODE_COLOR
)
#pos = nx.spring_layout(G)
# flesches
fleches_elem
=
set
(
cat
[
cat
.
objets
,
cat
.
objets
])
if
complet
:
func
=
lambda
x
,
y
:
cat
({
x
},{
y
})
else
:
func
=
lambda
x
,
y
:
cat
[{
x
},{
y
}]
for
source
,
cible
in
product
(
cat
.
objets
,
repeat
=
2
):
nb_fleches
=
0
for
fleche
in
func
(
source
,
cible
):
if
afficher_identites
or
not
fleche
.
is_identite
:
if
fleche
.
source
not
in
cat
.
objets
:
raise
Exception
(
"Source d'une fleche pas dans les objets de la categorie."
)
if
fleche
.
cible
not
in
cat
.
objets
:
raise
Exception
(
"Source d'une fleche pas dans les objets de la categorie."
)
if
len
({
obj
for
obj
in
cat
.
objets
if
obj
==
fleche
.
source
})
>
1
:
raise
Exception
(
"Plus d'un objet de la catégorie est source de la fleche."
)
if
len
({
obj
for
obj
in
cat
.
objets
if
obj
==
fleche
.
cible
})
>
1
:
raise
Exception
(
"Plus d'un objet de la catégorie est cible de la fleche."
)
#permet d'avoir toujours un objet de la catégorie comme source
source
=
{
obj
for
obj
in
cat
.
objets
if
obj
==
fleche
.
source
}.
pop
()
#permet d'avoir toujours un objet de la catégorie comme cible
cible
=
{
obj
for
obj
in
cat
.
objets
if
obj
==
fleche
.
cible
}.
pop
()
# descriptions
if
fleche
in
fleches_elem
:
G
.
add_edge
(
str
(
source
),
str
(
cible
),
color
=
parameters
.
EDGE_ELEMENTARY_COLOR
,
label
=
str
(
fleche
))
else
:
G
.
add_edge
(
str
(
source
),
str
(
cible
),
color
=
parameters
.
EDGE_NO_ELEMENTARY_COLOR
,
label
=
str
(
fleche
))
nb_fleches
+=
1
if
nb_fleches
>
limite_fleches
:
if
WARNING_LIMITE_FLECHES_ATTEINTE
:
print
(
"Warning : limite fleches entre "
+
str
(
source
)
+
" et "
+
str
(
cible
)
+
" atteinte."
)
break
return
G
\ No newline at end of file
GUI/tk/MainWindow.py
View file @
339eeee3
...
...
@@ -4,9 +4,9 @@ from tkinter import TOP, YES, BOTH, X, \
filedialog
,
messagebox
from
Parameters
import
parameters
from
tko.AppOgl
import
AppOgl
from
tk.OutilsFrame
import
OutilsFrame
from
tk.ObjetsFrame
import
ObjetsFrame
from
plot.PlotFrame
import
PlotFrame
class
MainWindow
:
...
...
@@ -16,9 +16,10 @@ class MainWindow:
def
getRoot
(
self
):
return
self
.
_root
_frame
=
None
_
gl
Frame
=
None
_
plot
Frame
=
None
_outFrame
=
None
_objFrame
=
None
def
getPlotFrame
(
self
):
return
self
.
_plotFrame
_glApp
=
None
_menu
=
None
...
...
@@ -46,11 +47,6 @@ class MainWindow:
self
.
_root
.
config
(
bg
=
"#787878"
)
def
_initFrames
(
self
):
# main frame
#test
#b=Button(self._root, text="test", command=lambda:self._controller.test(self._root))
#b.pack(fill=X)
# Frame
self
.
_frame
=
Frame
(
self
.
_root
)
self
.
_frame
.
pack
(
expand
=
YES
,
fill
=
BOTH
)
...
...
@@ -59,24 +55,19 @@ class MainWindow:
self
.
_frame
.
columnconfigure
(
2
,
weight
=
2
,
minsize
=
200
)
self
.
_frame
.
rowconfigure
(
0
,
weight
=
1
,
minsize
=
300
)
# OGL frame
self
.
_glFrame
=
Frame
(
self
.
_frame
)
self
.
_glFrame
.
grid
(
row
=
0
,
column
=
0
,
sticky
=
"nesw"
)
self
.
initGLApp
()
# Plot frame
self
.
_plotFrame
=
PlotFrame
(
self
.
_frame
,
self
.
_controller
)
self
.
_plotFrame
.
grid
(
row
=
0
,
column
=
0
,
sticky
=
"nesw"
)
# Outils frame
self
.
_outFrame
=
OutilsFrame
(
self
.
_frame
,
self
.
_controller
)
self
.
_outFrame
.
grid
(
row
=
0
,
column
=
1
,
sticky
=
"nesw"
)
# Objets frame
self
.
_objFrame
=
ObjetsFrame
(
self
.
_frame
,
self
.
_controller
)
self
.
_objFrame
=
ObjetsFrame
(
self
.
_frame
,
self
.
_controller
,
self
)
self
.
_objFrame
.
grid
(
row
=
0
,
column
=
2
,
sticky
=
"nesw"
)
def
initGLApp
(
self
):
self
.
_glApp
=
AppOgl
(
self
.
_glFrame
,
width
=
320
,
height
=
200
)
self
.
_glApp
.
pack
(
expand
=
YES
,
fill
=
BOTH
)
def
_initMenu
(
self
):
self
.
_menu
=
Menu
()
...
...
@@ -137,7 +128,31 @@ class MainWindow:
uids
=
self
.
_objFrame
.
getSelectedObjects
()
self
.
_controller
.
getModel
().
exporterGraphviz
(
uids
)
def
exportObjectsGraphviz
(
self
,
uids
):
print
(
f
"ddz
{
uids
}
"
)
self
.
_controller
.
getModel
().
exporterGraphviz
(
uids
)
"""
EXPORTS DIALOG CLASS
"""
class
ExportAsDialog
(
Toplevel
):
_registered
=
None
...
...
GUI/tk/ObjetsFrame.py
View file @
339eeee3
...
...
@@ -3,7 +3,7 @@
"""
from
pandas
import
DataFrame
from
tkinter
import
TOP
,
X
,
NO
,
W
,
Y
,
YES
,
BOTH
,
RIGHT
,
VERTICAL
,
\
Frame
,
Label
Frame
,
Label
,
Menu
from
tkinter.ttk
import
Treeview
,
Style
,
Scrollbar
from
ModelCallable
import
ModelCallable
...
...
@@ -12,23 +12,30 @@ from Model import Description
from
tk.InformFrame
import
InformFrame
from
tk.Factory
import
*
from
plot.PlotFrame
import
GraphGenerator
class
ObjetsFrame
(
Frame
,
ModelCallable
):
_controller
=
None
_mainWindow
=
None
_tree
=
None
_scrollbarY
=
None
_informFrame
=
None
_popupMenu
=
None
_popupObjectIid
=
None
_folders
=
{}
def
__init__
(
self
,
parent
,
controller
,
*
args
,
**
kwargs
):
assert
controller
def
__init__
(
self
,
parent
,
controller
,
mainWindow
,
*
args
,
**
kwargs
):
assert
controller
and
mainWindow
Frame
.
__init__
(
self
,
parent
,
*
args
,
**
kwargs
)
self
.
_controller
=
controller
self
.
_controller
.
getModel
().
registerModelCallable
(
self
)
self
.
_mainWindow
=
mainWindow
self
.
columnconfigure
(
0
,
weight
=
1
,
minsize
=
100
)
self
.
columnconfigure
(
1
,
minsize
=
16
)
#default value of scrollbar width
...
...
@@ -54,7 +61,7 @@ class ObjetsFrame(Frame, ModelCallable):
self
.
_tree
[
"columns"
]
=
(
"class"
,
"description"
)
self
.
_tree
.
column
(
"#0"
,
width
=
100
,
minwidth
=
15
,
stretch
=
False
)
self
.
_tree
.
column
(
"class"
,
width
=
5
0
,
stretch
=
False
)
self
.
_tree
.
column
(
"class"
,
width
=
1
5
,
stretch
=
False
)
self
.
_tree
.
column
(
"description"
,
width
=
200
,
minwidth
=
80
,
stretch
=
True
)
self
.
_tree
.
heading
(
"#0"
,
text
=
"UID"
,
anchor
=
W
)
...
...
@@ -64,9 +71,19 @@ class ObjetsFrame(Frame, ModelCallable):
self
.
_tree
.
bind
(
"<<TreeviewSelect>>"
,
self
.
objectSelection
)
self
.
_tree
.
bind
(
"<Delete>"
,
self
.
objectSelection
)
# popup tree menu
self
.
_popupMenu
=
Menu
(
self
.
_tree
,
tearoff
=
0
)
self
.
_popupMenu
.
add_command
(
label
=
"NetworkX"
,
command
=
self
.
toNetworkX
)
self
.
_popupMenu
.
add_command
(
label
=
"Graphviz"
,
command
=
self
.
toGraphviz
)
self
.
_tree
.
bind
(
"<Button-3>"
,
self
.
popup
)
# Button-2 on Aqua
# INFORM
self
.
_informFrame
=
InformFrame
(
self
)
self
.
_informFrame
.
grid
(
row
=
2
,
columnspan
=
2
,
column
=
0
,
sticky
=
"nesw"
)
"""
GETTERS
"""
...
...
@@ -132,7 +149,7 @@ class ObjetsFrame(Frame, ModelCallable):
"""
BIND FUNCTIONS
BIND FUNCTIONS
/MENU FUNCTIONS
"""
def
objectSelection
(
self
,
event
):
curItems
=
self
.
_tree
.
selection
()
...
...
@@ -147,7 +164,30 @@ class ObjetsFrame(Frame, ModelCallable):
self
.
_informFrame
.
setText
(
text
)
def
objectDelete
(
self
,
event
):
print
(
self
.
_tree
.
focus
())
pass
def
popup
(
self
,
event
):
try
:
iid
=
self
.
_tree
.
identify_row
(
event
.
y
)
if
iid
:
self
.
_popupMenu
.
tk_popup
(
event
.
x_root
,
event
.
y_root
,
0
)
if
self
.
_tree
.
parent
(
iid
):
self
.
_popupObjectIid
=
int
(
iid
)
else
:
pass
finally
:
self
.
_popupMenu
.
grab_release
()
def
toNetworkX
(
self
):
if
self
.
_popupObjectIid
is
not
None
:
self
.
_mainWindow
.
getPlotFrame
().
setGraph
(
GraphGenerator
.
give
(
self
.
_controller
.
getModel
().
getObject
(
self
.
_popupObjectIid
)[
'object'
]))
self
.
_popupObjectIid
=
None
def
toGraphviz
(
self
):
if
self
.
_popupObjectIid
is
not
None
:
self
.
_mainWindow
.
exportObjectsGraphviz
([
self
.
_popupObjectIid
])
self
.
_popupObjectIid
=
None
...
...
GUI/tk/OutilsFrame.py
View file @
339eeee3
...
...
@@ -27,3 +27,5 @@ class OutilsFrame(Frame):
NOFrame
=
NewObjectFrame
(
self
,
self
.
_controller
.
getModel
())
NOFrame
.
grid
(
row
=
1
,
column
=
0
,
sticky
=
"nwe"
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment