Pymecavideo 8.0
Étude cinématique à l'aide de vidéos
export.py
1"""
2 export.py is a module of pymecavideo.
3 pymecavideo is a program to track moving points in a video frameset
4 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa@gmail.com>
5 Copyright (C) 2023 Georges Khaznadar <georgesk@debian.org>
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19"""
20
21"""
22export.py permet d'exporter les données de pymecavideo dans différents formats
23"""
24
25
26from globdef import DOCUMENT_PATH, HOME_PATH
27from PyQt6.QtWidgets import QFileDialog, QCheckBox, QDialog, QMessageBox
28from PyQt6.QtCore import Qt, QCoreApplication, QUrl, QStandardPaths
29import sys
30import os, time
31
32# On prévient si l'enregistrement est un succès ?
33INFO_OK = False
34
35# Dictionnaire contenant les différents formats d'exportation
36# nom (str) : nom du format/de l'application
37# filtre (str) : filtre utilisé dans le dialogue d'enregistrement
38# extension (str) : extension du fichier, ajoutée automatiquement si besoin
39# class (str) : classe appelée pour générer et enregistrer le fichier
40# propose_ouverture (bool) : propose ou pas l'ouverture du ficher dans le dialogue d'enregistrement
41# modules (list of str) : liste des modules non standards nécessaires ou None
42# un_point (bool) : nécessite un seul point cliqué ou pas
43EXPORT_FORMATS = {
44 1: {'nom': QCoreApplication.translate("export", 'Libre/OpenOffice Calc'),
45 'filtre': QCoreApplication.translate("export", 'Feuille de calcul OpenDocument (*.ods)'),
46 'extension': 'ods',
47 'class': 'Calc',
48 'modules': ['odf'],
49 'propose_ouverture': True,
50 'un_point': False},
51
52 2: {'nom': QCoreApplication.translate("export", 'Python (source)'),
53 'filtre': QCoreApplication.translate("export", 'Fichier Python (*.py)'),
54 'extension': 'py',
55 'class': 'PythonSource',
56 'modules': None,
57 'propose_ouverture': True,
58 'un_point': True},
59
60 3: {'nom': QCoreApplication.translate("export", 'Python (Numpy)'),
61 'filtre': QCoreApplication.translate("export", 'Fichier Numpy (*.npy)'),
62 'extension': 'npy',
63 'class': 'PythonNumpy',
64 'modules': ['numpy'],
65 'propose_ouverture': False,
66 'un_point': True},
67
68 4: {'nom' : QCoreApplication.translate("export",'Jupyter Notebook'),
69 'filtre' : QCoreApplication.translate("export",'Notebook (*.ipynb)'),
70 'extension' : 'ipynb',
71 'class' : 'PythonNotebook',
72 'modules' : ['nbformat'],
73 'propose_ouverture' : False,
74 'un_point' : True},
75
76 5: {'nom': QCoreApplication.translate("export", 'Fichier CSV'),
77 'filtre': QCoreApplication.translate("export", 'Fichier CSV (*.csv, *.txt)'),
78 'extension': 'csv',
79 'class': 'FichierCSV',
80 'modules': None,
81 'propose_ouverture': True,
82 'un_point': False},
83
84 6: {'nom': QCoreApplication.translate("export", 'Pandas Dataframe'),
85 'filtre': QCoreApplication.translate("export", 'Dataframe (*.pkl)'),
86 'extension': 'pkl',
87 'class': 'DataframePandas',
88 'modules': ['pandas'],
89 'propose_ouverture': False,
90 'un_point': False},
91}
92
93# Dictionnaire contenant les textes des QMessageBox information, warning...
94EXPORT_MESSAGES = {
95 0: {'titre': QCoreApplication.translate("export", "Erreur lors de l'exportation"),
96 'texte': QCoreApplication.translate("export", "Echec de l'enregistrement du fichier:<b>\n{0}</b>")},
97
98 1: {'titre': QCoreApplication.translate("export", "Impossible de créer le fichier"),
99 'texte': QCoreApplication.translate("export", "L'export n'est possible que pour 1 seul point cliqué.")},
100
101 2: {'titre': QCoreApplication.translate("export", "Exportation terminée"),
102 'texte': QCoreApplication.translate("export", "Fichier:\n<b>{0}</b>\nenregistré avec succès.")},
103
104 3: {'titre': QCoreApplication.translate("export", "Impossible de créer le fichier"),
105 'texte': QCoreApplication.translate("export", "Le module <b>{0}</b> n'est pas installé.")},
106}
107
108
109# CLASSES D'EXPORT DANS LES DIFFERENTS FORMATS
110# En début de fichier pour qu'elles apparaissent dans globals()
111# =============================================================
112
114
115 def __init__(self, app, filepath):
116 """
117 Crée un fichier Pandas et importe les données de pymecavideo
118 """
119 import pandas as pd
120 self.DataFrame = pd.DataFrame
121 table = app.tableWidget
122 df = self.write_qtable_to_df(table)
123 df.to_pickle(filepath)
124 QMessageBox.information(
125 None,
126 QCoreApplication.translate("export_pandas", "Fichier Pandas sauvegardé"),
127 QCoreApplication.translate(
128 "export_pandas", """Pour ouvrir ce fichier depuis Python, taper :\n\nimport pandas as pd\ndf = pd.read_pickle("{}")""".format(os.path.basename(filepath))))
129
130 def write_qtable_to_df(self, table):
131 """
132 https://stackoverflow.com/questions/37680981/how-can-i-retrieve-data-from-a-qtablewidget-to-dataframe
133 """
134 #col_count = table.columnCount()
135 #modif pour gérer 'refaire le point'
136 col_count = table.columnCount()-1
137 row_count = table.rowCount()
138 headers = [str(table.horizontalHeaderItem(i).text())
139 for i in range(col_count)]
140 df_list = []
141 for row in range(row_count):
142 df_list2 = []
143 for col in range(col_count):
144 table_item = table.item(row, col)
145 df_list2.append(
146 '' if table_item is None else float(table_item.text()))
147 df_list.append(df_list2)
148 df = self.DataFrame(df_list, columns=headers)
149 return df
150
151
153
154 def __init__(self, app, filepath):
155 """
156 Crée un fichier CSV et exporte les données de pymecavideo
157 """
158 import csv
159 d = CsvExportDialog(app)
160 if d.exec() == QDialog.DialogCode.Accepted:
161 _decimal = d.decimal
162 _field = d.field
163 _header = d.checkBox.isChecked()
164 tw = app.tableWidget
165 with open(filepath, 'w', newline='') as csvfile:
166 csvwriter = csv.writer(csvfile, delimiter=_field,
167 quotechar='"', quoting=csv.QUOTE_MINIMAL)
168 if _header:
169 header = [tw.horizontalHeaderItem(
170 col).text() for col in range(tw.columnCount()-1)]
171 csvwriter.writerow(header)
172 for row in range(tw.rowCount()):
173 rowdata = []
174 #for col in range(tw.columnCount()-1):
175 #modif pour gérer 'refaire le point'
176 for col in range(tw.columnCount()-1):
177 item = tw.item(row, col)
178 if item is not None:
179 txt = item.text()
180 if _decimal == ',':
181 txt = txt.replace('.', ',')
182 rowdata.append(txt)
183 else:
184 rowdata.append('')
185 csvwriter.writerow(rowdata)
186
187
188class Calc():
189 """
190 Objet capable d'écrire des données textes et numériques dans
191 un fichier au fomat ODS
192 """
193
194 def __init__(self, app, fichier_ods):
195 """
196 Crée un fichier ods et importe les données de pymecavideo
197 """
198 from odf.opendocument import OpenDocumentSpreadsheet
199 from odf.text import P
200 from odf.table import Table, TableRow, TableCell
201 self.P = P
202 self.TableRow = TableRow
203 self.TableCell = TableCell
204 self.outfile = open(fichier_ods, 'wb')
205 self.doc = OpenDocumentSpreadsheet()
206 self.table = Table(name="Pymecavideo {0}".format(
207 time.strftime("%Y-%m-%d %Hh%Mm%Ss")))
208 self.exportpymeca(app)
209
210 def exportpymeca(self, app):
211 """
212 exporte les données de pymecavideo
213 @param app pointeur vers l'application
214 """
215 # fait une ligne de titres
216 titles = ["t (s)"]
217 for obj in app.pointage.suivis:
218 titles.append(f"X{obj} (m)")
219 titles.append(f"Y{obj} (m)")
220 row = self.TableRow()
221 self.table.addElement(row)
222 for t in titles:
223 tc = self.TableCell()
224 row.addElement(tc)
225 para = self.P(text=t)
226 tc.addElement(para)
227
228
229 self.tr = []
230 def cb_temps(i,t):
231 """
232 fonction de rappel qui crée les lignes de tableur et
233 y inscrit la date, à gauche; construit self.tr la liste des
234 pointeurs vers les lignes du tableur
235 """
236 row = self.TableRow()
237 self.tr.append(row)
238 self.table.addElement(row)
239 row.addElement(
240 self.TableCell(valuetype="float", value=str(t)))
241 return
242
243 def cb_point(i, t, j, obj, p, v):
244 """
245 fonction de rappel qui inscrit les coordonnées dans le tableur
246 """
247 if p is None: return
248 self.tr[i].addElement(
249 self.TableCell(valuetype="float", value=str(p.x)))
250 self.tr[i].addElement(
251 self.TableCell(valuetype="float", value=str(p.y)))
252 return
253
254 # écrit dans toutes les cases du tableur
255 app.pointage.iteration_data(cb_temps, cb_point, unite="m")
256 # accroche la feuille au document tableur
257 self.doc.spreadsheet.addElement(self.table)
258 # écrit dans le fichier de sortie
259 self.doc.save(self.outfile)
260 self.outfile.close()
261 return
262
263class PythonSource:
264 """
265 Exporte les données dans un fichier Python(source)
266 """
267
268 # lignes de code en tête du programme Python
269 en_tete = """\
270#!/usr/bin/env python3
271## Données exportées de Pymecavidéo
272## {date}
273import numpy as np
274import matplotlib.pyplot as plt
276# Intervalle de temps auto-détecté
277dt={deltaT}
278"""
279
280 # lignes de code a écrire dans tous les cas, après l'en-tête
281 code = """
282
283 ##############################################################
284 # Le code auto-généré qui suit peut être effacé à volonté. #
285 ##############################################################
286 # Il n'est là qu'à titre d'exemple, et il n'est pas toujours #
287 # approprié à l'usage des données que vous avez exportées. #
288 ##############################################################
289
290 ## affichage des points
291 plt.plot(x1,y1,'o',markersize= 3)
292 plt.xlabel("x (en m)")
293 plt.ylabel("y (en m)")
294
295 ## calcul et affichage des vecteurs vitesses
296
297
298
299 {cv}
300 {vv}
301
302 ## calcul et affichage des vecteurs accélérations
303
304 {ca}
305 {va}
306
307 ## présentation du diagramme interactif
308 plt.grid()
309 plt.show()
310 """
311
312 # lignes de code si on veut calculer les vitesses
313 cv1 = """
314 Δt = 2*dt
315 vx = np.array(np.zeros(len(x1)-2))
316 vy = np.array(np.zeros(len(x1)-2))
317 i=0
318 for k in range(1,len(x1)-1):
319 Δx = (x1[k+1]-x1[k-1])
320 Δy = (y1[k+1]-y1[k-1])
321 vx[i] = Δx/Δt
322 vy[i] = Δy/Δt
323 i+=1
324"""
325
326 # lignes de code si on ne veut pas calculer la vitesse
327 cv0 = """
328##### à compléter pour calculer les vitesses ####
329 ##############
330 ##############
331"""
332 # lignes de code activables éventuellement dans l'éditeur, afin
333 # de tracer les vecteurs vitesse
334 vv = """
335 #Pour afficher les vecteurs vitesses, décommentez la ligne suivante quand le code précédent est prêt.
336 #plt.quiver(x1[1:-1], y1[1:-1], vx, vy, scale_units = 'xy', angles = 'xy', width = 0.003)
337 """
338
339 # lignes de code si on veut calculer l'accélération
340 ca1 = """
341 ax = np.array(np.zeros(len(vx)-2))
342 ay = np.array(np.zeros(len(vx)-2))
343 i=0
344 for k in range(1, len(vx)-1):
345 Δvx = (vx[k+1]-vx[k-1])
346 Δvy = (vy[k+1]-vy[k-1])
347 ax[i] = Δvx/Δt
348 ay[i] = Δvy/Δt
349 i+=1"""
350
351 # lignes de code si on ne veut pas calculer l'accélération
352 ca0 = """#####à compléter pour calculer les vitesses####
353 ##############
354 ##############"""
355
356 # lignes de code si on veut voir les vecteurs accélération
357 va = """
358 plt.title("Vecteurs accélérations")
359 plt.quiver(x1[2:-2], y1[2:-2], ax, ay, scale_units = 'xy', angles = 'xy', width = 0.003, color = 'r')
360"""
361
362 def __init__(self, app, filepath):
363 # traitement du scénario des vitesses/accélrations :
364 # si seule la vitesse est cochée, on calcule et affiche les vitesses
365 # si les deux sont cochées, on calcule et affiche les vitesses et accélérations
366 # si seule l'accélération est cochée, les vitesses sont calculées mais non affichées
367 #self.dbg.p(2, "rentre dans 'python source2'")
368 d = PythonExportDialog(app)
369 if d.exec() == QDialog.DialogCode.Accepted:
370 calcule_vitesse, affiche_vitesse, calcule_accel, affiche_accel = \
371 d.checkBox_v.isChecked(), \
372 d.checkBox_v2.isChecked(), \
373 d.checkBox_a.isChecked(), \
374 d.checkBox_a2.isChecked()
375 if affiche_vitesse:
376 calcule_vitesse = True
377 if calcule_accel or affiche_accel:
378 "on veut les accelerations, il faut les vitesse"
379 calcule_vitesse = True
380 if affiche_accel:
381 calcule_accel = True
382 calcule_vitesse = True
383 with open(filepath, "w", encoding="UTF-8") as f:
384 date = time.strftime("%d/%m/%y %H:%M")
385 f.write(self.en_tete.format(date=date, deltaT=app.pointage.deltaT))
386
387 commentaires = []
388 lignes_x = []
389 lignes_y = []
390
391 def cb_objet(i, obj):
392 """
393 fonction de rappel pour chacun des objets; modifie les listes
394 commentaires, lignes_x et lignes_y
395 @param i index de l'objet, commençant à 0
396 @param obj un objet suivi
397 """
398 commentaires.append(f"""\
399
400# coordonnées du point numéro {obj}
401
402""")
403 lignes_x.append(f"x{obj} = np.array([")
404 lignes_y.append(f"y{obj} = np.array([")
405 return
406
407
408 def cb_point(i, obj, p):
409 """
410 fonction de rappel pour les points pointés appartenant à un
411 objet
412 @param i l'index de l'objet, commençant à 0
413 @param obj l'objet suivi
414 @param p un pointage (de type vecteur)
415 """
416 if p is not None:
417 lignes_x[i] += f"{p.x}, "
418 lignes_y[i] += f"{p.y}, "
419 return
420
421 # on crée les commentaires et les lignes de déclaration de
422 # tableaux de nombres
423 app.pointage.iteration_objet(cb_objet, cb_point, unite="m")
424
425 # On termine les lignes de déclaration des tableaux de nombres
426 lignes_x = [l + "])\n" for l in lignes_x]
427 lignes_y = [l + "])\n" for l in lignes_y]
428
429
430 for c, lx, ly in zip(commentaires, lignes_x, lignes_y):
431 f.write(c); f.write(lx); f.write(ly)
432 f.write(self.code.format(
433 cv = self.cv1 if calcule_vitesse else self.cv0,
434 vv = self.vv,
435 ca = self.ca1 if calcule_accel else self.ca0,
436 va = self.va if affiche_accel else "",
437 ))
438 return
439
440from interfaces.Ui_csv_dialog import Ui_Dialog as Ui_csv_Dialog
441
442class CsvExportDialog(QDialog, Ui_csv_Dialog):
443 """
444 Fenêtre de dialogue permettant de choisir séparateurs de champ et décimal dans le fichier CSV
445 """
446
447 def __init__(self, *args, **kwargs):
448 QDialog.__init__(self, *args, **kwargs)
449 Ui_csv_Dialog.__init__(self)
450 self.setupUi(self)
451 self.change_field()
452 self.change_dec()
453 return
455 def change_field(self):
456 if self.rbFieldComma.isChecked():
457 self.field = ","
458 elif self.rbFieldSemicolon.isChecked():
459 self.field = ";"
460 elif self.rbFieldTab.isChecked():
461 self.field = "\t"
462 return
463
464 def change_dec(self):
465 if self.rbFieldComma.isChecked():
466 self.decimal = ","
467 elif self.rbDecDot.isChecked():
468 self.decimal = "."
469 return
470
471 def check_if_dot(self):
472 if self.rbDecComma.isChecked():
473 if self.rbFieldComma.isChecked():
474 self.rbFieldSemicolon.setChecked(True)
475 self.rbFieldComma.setEnabled(False)
476 else:
477 self.rbFieldComma.setEnabled(True)
478 self.change_field()
479 return
480
481from interfaces.Ui_python_dialog import Ui_Dialog as Ui_Python
482
483class PythonExportDialog(QDialog, Ui_Python):
484 """
485 Fenêtre de dialogue permettant de choisir les grandeurs à exporter
486 dans le fichier Python(source)
487 """
488
489 def __init__(self, *args, **kwargs):
490 QDialog.__init__(self, *args, **kwargs)
491 Ui_Python.__init__(self)
492 self.setupUi(self)
493 return
494
495class PythonNumpy:
496 """
497 Exporte les données dans un fichier Numpy
498 """
499
500 def __init__(self, app, filepath):
501 import numpy as np
502
503 liste_temps = app.pointage.liste_t_pointes()
504
505 x_objets = {o: [] for o in app.pointage.suivis}
506 y_objets = {o: [] for o in app.pointage.suivis}
507 def cb_points(i, t, j, obj, p, v):
508 """
509 fonction de rappel pour chaque point
510 """
511 if p is None: return
512 x_objets[obj].append(p.x)
513 y_objets[obj].append(p.y)
514 return
515
516 app.pointage.iteration_data(None, cb_points, unite = "m")
517
518 export = [liste_temps]
519 for obj in app.pointage.suivis:
520 export.append(x_objets[obj])
521 export.append(y_objets[obj])
522
523 np.save(filepath, export)
524 QMessageBox.information(
525 None,
526 QCoreApplication.translate("export_numpy", "Fichier Numpy sauvegardé"),
527 QCoreApplication.translate("export_numpy",
528 """Pour ouvrir ce fichier depuis Python, taper :
529
530import numpy as np\nt,x1,y1 ... = np.load("{}")""".format(
531 os.path.basename(filepath))))
532 return
533from interfaces.Ui_jupyter_dialog import Ui_Dialog as Jupyter_Dialog
534
535class NotebookExportDialog(QDialog, Jupyter_Dialog):
536 """
537 Fenêtre de dialogue permettant de choisir les grandeurs à exporter
538 dans le fichier Notebook Jupyterlab
539 """
540
541 def __init__(self, *args, **kwargs):
542 QDialog.__init__(self, *args, **kwargs)
543 Jupyter_Dialog.__init__(self)
544 self.setupUi(self)
545 return
546
547 def etat_vitesse(self,etat):
548 if etat == 0 :
549 for w in (self.checkBox_v2, self.checkBox_a, self.checkBox_e):
550 w.setChecked(False)
551 w.setEnabled(False)
552 else :
553 for w in (self.checkBox_v2, self.checkBox_a, self.checkBox_e):
554 w.setEnabled(True)
555 return
556
557
558class PythonNotebook :
559 """
560 Exporte les données dans un fichier Notebook Jupyterlab
561 Attention : seul le premier objet est exporté !
562 """
563 def __init__(self, app, filepath):
564 import nbformat as nbf
565 from template_ipynb import genere_notebook
566 ligne_t = "np.array({})".format(app.pointage.liste_t_pointes())
567 points = app.pointage.liste_pointages()
568 ligne_x = "np.array({})".format([p.x for p in points])
569 ligne_y = "np.array({})".format([p.y for p in points])
570 d = NotebookExportDialog(app)
571 if d.exec() == QDialog.DialogCode.Accepted:
572 graphs = (d.checkBox_c.isChecked(), d.checkBox_v.isChecked(
573 ), d.checkBox_v2.isChecked(), d.checkBox_a.isChecked(), d.checkBox_e.isChecked())
574 nb = genere_notebook((ligne_t, ligne_x, ligne_y), graphs = graphs)
575 nbf.write(nb, filepath)
576 return
577
578class SaveThenOpenFileDialog(QFileDialog):
579 """
580 Enregistre un fichier et propose de l'ouvrir ensuite
581 """
582
583 def __init__(self, *args, extension=None, proposeOuverture=True):
584 super().__init__(*args)
585 self.setOption(QFileDialog.Option.DontUseNativeDialog)
586 self.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)
587 #self.setWindowFlags(self.windowFlags() & ~Qt.WindowFlags.Dialog)
588 urls = [QUrl.fromLocalFile(DOCUMENT_PATH),
589 QUrl.fromLocalFile(HOME_PATH),
590 QUrl.fromLocalFile(QStandardPaths.writableLocation(QStandardPaths.StandardLocation.DesktopLocation))
591 ]
592 self.setSidebarUrls(urls)
593 self.setDefaultSuffix(extension)
594 self.checkbox = QCheckBox(self)
595 self.checkbox.setStyleSheet("color: rgb(255, 0, 0);")
596 self.checkbox.setText("Ouvrir le fichier après enregistrement")
597 self.layout().addWidget(self.checkbox)
598 if not proposeOuverture:
599 self.checkbox.setVisible(False)
600
601# CLASSE PRINCIPALE
602# en fin de fichier pour récupérer les globals()
603# ==============================================
604
605
606class Export:
607 """
608 Une classe qui gère l'exportation des données
609
610 paramètres du constructeur
611 @param coord le widget principale de l'onglet coodonnées
612 """
613
614 def __init__(self, coord, choix_export):
615 self.coord = coord
616 self.app = coord.app
617 self.pointage = coord.pointage
618 self.dbg = coord.dbg
619 self.dbg.p(1, "rentre dans 'Export'")
620 propose_ouverture = EXPORT_FORMATS[choix_export]['propose_ouverture']
621 base_name = os.path.splitext(os.path.basename(self.pointage.filename))[0]
622 filtre = EXPORT_FORMATS[choix_export]['filtre']
623 extension = EXPORT_FORMATS[choix_export]['extension']
624 self.class_str = EXPORT_FORMATS[choix_export]['class']
625 un_point = EXPORT_FORMATS[choix_export]['un_point']
626 modules = EXPORT_FORMATS[choix_export]['modules']
627 # On vérifie si les modules additionnels sont présents
628 if modules:
629 for mod in modules:
630 try:
631 m = __import__(mod)
632 except ImportError:
633 self.dbg.p(3, "erreur d'export")
634 self.dbg.p(3, EXPORT_MESSAGES)
635 msg = EXPORT_MESSAGES[3]
636 QMessageBox.critical(None, msg['titre'], msg['texte'].format(
637 mod))
638 return
640 base_name, filtre, extension, propose_ouverture)
641 return
642
643 def demande_nom_fichier(self, filename, filtre, extension, propose_ouverture):
644 defaultName = os.path.join(DOCUMENT_PATH, filename)
645 fd = SaveThenOpenFileDialog(None, 'Exporter...', defaultName,
646 filtre, extension=extension, proposeOuverture=propose_ouverture)
647 ouvre = False
648 if fd.exec() == QDialog.DialogCode.Accepted:
649 filepath = fd.selectedFiles()[0]
650 ouvre = fd.checkbox.isChecked()
651 # self.enregistre_fichier(filepath)
652 self.enregistre_fichier(filepath)
653 if INFO_OK:
654 msg = EXPORT_MESSAGES[2]
655 QMessageBox.information(None, msg['titre'], msg['texte'].format(
656 filepath))
657 if ouvre:
658 self.ouvre_fichier(filepath)
659 return
660
661 def enregistre_fichier(self, filepath):
662 """
663 Redirige vers la routine d'exportation qui est définie par
664 self.class_str
665 """
666 dynamic_class = globals()[self.class_str]
667 dynamic_class(self.coord, filepath)
668
669 def ouvre_fichier(self, filepath):
670 if sys.platform.startswith('linux'):
671 os.system("xdg-open "+filepath)
672 elif sys.platform.startswith('darwin'):
673 os.system("open "+filepath)
674 elif sys.platform.startswith('win'):
675 os.startfile(os.path.realpath(filepath))
Objet capable d'écrire des données textes et numériques dans un fichier au fomat ODS.
Definition: export.py:201
def exportpymeca(self, app)
exporte les données de pymecavideo
Definition: export.py:223
def __init__(self, app, fichier_ods)
Crée un fichier ods et importe les données de pymecavideo.
Definition: export.py:206
Fenêtre de dialogue permettant de choisir séparateurs de champ et décimal dans le fichier CSV.
Definition: export.py:454
def write_qtable_to_df(self, table)
https://stackoverflow.com/questions/37680981/how-can-i-retrieve-data-from-a-qtablewidget-to-dataframe
Definition: export.py:133
def __init__(self, app, filepath)
Crée un fichier Pandas et importe les données de pymecavideo.
Definition: export.py:118
Une classe qui gère l'exportation des données.
Definition: export.py:621
def ouvre_fichier(self, filepath)
Definition: export.py:678
def enregistre_fichier(self, filepath)
Redirige vers la routine d'exportation qui est définie par self.class_str.
Definition: export.py:674
def demande_nom_fichier(self, filename, filtre, extension, propose_ouverture)
Definition: export.py:652
def __init__(self, app, filepath)
Crée un fichier CSV et exporte les données de pymecavideo.
Definition: export.py:157
Fenêtre de dialogue permettant de choisir les grandeurs à exporter dans le fichier Notebook Jupyterla...
Definition: export.py:548
Fenêtre de dialogue permettant de choisir les grandeurs à exporter dans le fichier Python(source)
Definition: export.py:496
Exporte les données dans un fichier Notebook Jupyterlab Attention : seul le premier objet est exporté...
Definition: export.py:571
Exporte les données dans un fichier Numpy.
Definition: export.py:507
def __init__(self, app, filepath)
fonction de rappel pour chaque point
Definition: export.py:509
Exporte les données dans un fichier Python(source)
Definition: export.py:275
def __init__(self, app, filepath)
fonction de rappel pour chacun des objets; modifie les listes commentaires, lignes_x et lignes_y
Definition: export.py:371
Enregistre un fichier et propose de l'ouvrir ensuite.
Definition: export.py:590