Bonjour, (et désolé, encore probablement une évidence de syntaxe Python)
La doc python dit bien que, dans une classe, tout ce qui n'est pas spécifié privé est public.
Or, l'appel de "outData()" me donne l'erreur :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
cs@cs-Vaio:~/Documents/Ateliers/Atl-Log/AptBureau$ python AptBureau.py
False
False
Bandes
Dans EditeBandes
True
Traceback (most recent call last):
  File "/home/cs/Documents/Ateliers/Atl-Log/AptBureau/AptBureauUI.py", line 48, in EditeBandes
    self.EditeTouteTable(Archive.BandesCSV)
  File "/home/cs/Documents/Ateliers/Atl-Log/AptBureau/AptBureauUI.py", line 54, in EditeTouteTable
    TableBandes.outData() #self.tableView.model.outData()
AttributeError: 'builtin_function_or_method' object has no attribute 'outData'
cs@cs-Vaio:~/Documents/Ateliers/Atl-Log/AptBureau$
Notez que à la ligne 121, self.UIParent.flagsDataChanged= True fonctionne très bien.
C'est ce qui me fait entrer dans le stockage des données modifiées dans "EditeTouteTable"

Le code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Classes de base du UI de AptBureau
# Début: 23 nov 2019
 
from PySide2 import Qt, QtCore, QtWidgets, QtGui
import operator
 
import mainwindow
import Archive
import BandesPourAptQGis
 
class AptBureauWin(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
    def __new__(self):
        if not hasattr(self, 'instance'):
            self.instance = super(AptBureauWin, self).__new__(self)
            self.instanceinit=0
        else: self.instanceinit=1 # ligne inutile (à tester)
        return self.instance
 
    def __init__(self, parent=None):
        if not self.instanceinit==0: return
        super(AptBureauWin, self).__init__(parent)
        self.instanceinit=1
        self.setupUi(self)
 
        self.setWindowIcon(QtGui.QIcon('AptVerger.svg'))
 
        self.actionEnregistrer.triggered.connect(Archive.ArchiveDonnees)
        self.actionOpen.triggered.connect(Archive.LireCSV)  #Archive.ChargeDonnees)
        self.actionContr_le_des_bandes.triggered.connect(BandesPourAptQGis.ArchiveShapeFileGeoJason)
        self.action_Bandes_2.triggered.connect(self.EditeBandes)
 
        header = self.tableView.horizontalHeader()
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)       
        header.setStretchLastSection(True)
        self.tableView.setSortingEnabled(True)
        # futur : pas de sort sur dernière colonne
        # ? : pourquoi un sort sur la première colonne (en ordre descendant) s'execute au démarrage ?
        # sans cliquer sur l'entête de colonne 
 
        self.idDatas = {'Bandes':0,'Cultures':1,'Actions':2, 'Productions':3, 'Actes':4}
        self.flagsDataChanged = False #[False, True, False, False, False]
        self.EnCoursEdition= None
 
        self.EditeTouteTable(Archive.BandesCSV) # futur : en fait mettre "Actes" ici
 
    def EditeBandes(self):
        print("Dans EditeBandes")
        self.EditeTouteTable(Archive.BandesCSV)
 
    def EditeTouteTable(self, tableDatas):
        print(self.flagsDataChanged)
        if self.flagsDataChanged: """ Stockage des données modifiées """
            TableBandes= self.tableView.model
            TableBandes.outData() #self.tableView.model.outData()
            print(self.EnCoursEdition)
            #Archive.ArchiveDonnees()
            self.flagsDataChanged = False
        print(self.flagsDataChanged)
        #TableBandes= TouteTableModel(tableDatas, self)
        #self.tableView.setModel(TableBandes)
        print(tableDatas[0][0])
        self.tableView.setModel(TouteTableModel(tableDatas, self))
        self.EnCoursEdition=tableDatas
 
class TouteTableModel(QtCore.QAbstractTableModel):
    def __init__(self, datain, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self.headers = datain[0]
        self.arraydata = datain[1:]
        self.types = tuple(type(item).__name__ for item in self.arraydata[0])
        #print(self.types)
        # donne : ('str', 'float', 'int', 'int', 'int', 'str', 'str')
        self.UIParent= parent
        #print(self.UIParent.flagsDataChanged)
 
    def outData(self):
        self.UIParent.EnCoursEdition= self.arraydata
 
    def rowCount(self, parent): return len(self.arraydata)
 
    def columnCount(self, parent): return len(self.headers)
 
    def data(self, index, role):
        if not index.isValid(): return QVariant()
        elif role == QtCore.Qt.EditRole: return None
        elif role != QtCore.Qt.DisplayRole: return None
        for i, ligne  in enumerate(self.arraydata):
            if i == index.row(): return ligne[index.column()]
 
    def headerData(self, section, orientation, role):
        if role != QtCore.Qt.DisplayRole: return None
        if orientation == QtCore.Qt.Horizontal: return self.headers[section]
        else: return "{}".format(section)
 
    def sort(self, col, order): #trier la table sur la colonne col selon order
        self.layoutAboutToBeChanged.emit()
        self.arraydata = sorted(self.arraydata,key=operator.itemgetter(col),
            reverse=(order == QtCore.Qt.SortOrder.DescendingOrder))
        self.layoutChanged.emit()
 
    def addRow(self):
        self.layoutAboutToBeChanged.emit()
        self.arraydata.append(['bande', 'lati', 'longi', 'long', 'larg', 'NS/EO', 'texte'])
        self.layoutChanged.emit()
 
    def removeRow(self, row):
        if 0 <= row < self.rowCount():
            self.layoutAboutToBeChanged.emit()
            del self.arraydata[row]
            self.layoutChanged.emit()
 
    def setData(self, index, value, role = QtCore.Qt.EditRole):
        if index.isValid():
            if role == QtCore.Qt.EditRole:
                row = index.row()
                col = index.column()
                if self.types[col] in ('int', 'float'): #['int', 'float']:
                    self.arraydata[row][col] = float(value.replace(",","."))
                elif self.types[col] == 'str': self.arraydata[row][col] = str(value)
                else: print('type incompatible') # futur : liste de coordonnées pour longueur
                self.UIParent.flagsDataChanged= True
                return True
            else: return False
        else: return False
 
    def flags(self, index):
        return QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsEnabled
 
"""
class MyDelegate(QtWidgets.QItemDelegate):
    def __init__(self, parent = None):
        super(MyDelegate, self).__init__(parent)
        self.view = parent
 
    def eventFilter(self, editor, event):
        # there is a lot of checking in order to identify the desired situation and avoid errors
        if isinstance(event, QtGui.QKeyEvent):
            if event.type() == QtCore.QEvent.KeyPress:
                if event.key() == QtCore.Qt.Key_Escape:
                    # we should have a list here of length one (due to selection restrictions on the view)
                    index = self.view.selectedIndexes()
                    if index:
                        if index[0].isValid():
                            row = index[0].row()
                            self.view.model().removeRow(row)
"""