IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Problème de mise à jour d'une vue avec un delegate perso [QtGui]


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 18
    Points
    18
    Par défaut Problème de mise à jour d'une vue avec un delegate perso
    Bonjour,

    J'essaye de développer une application en python en utilisant les composants suivants:

    Python V 2.7.11 sur windows
    Pyside V 1.2.4
    QTcore 4.8.7

    L'application devra charger une table SQLITE et l'afficher dans une vue.
    Une modification d'un des éléments de la table au moyen de la vue doit être marquée rouge et ne doit pas être prise en compte tant que l'on a pas appuyé sur un bouton 'save'.
    Pour cela, j'ai parcouru les documentations MVC de QT et j'ai bien vu qu'il fallait que je me fasse un 'delegate' perso.
    J'ai un petit bug..
    Quand j'édite une cellule, celle-ci est bien marquée rouge mais le nouveau texte n'est pas encore affiché tant que je n'ai pas fait un submitAll() sur le modèle.
    Je n'arrive pas à trouver le moyen d'y arriver.
    Bien sur, on peut toujours changer la stratégie du modèle qui est actuellement définie en SqlTableModel.OnManualSubmit mais du coup je perds l'intérêt du bouton save.
    voici 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
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
     
     
    from __future__ import (print_function, division, unicode_literals,
                            absolute_import)
     
    import os
    import sys
    import PySide
     
    #from PySide.QtCore import Slot, QMetaObject, Qt, QRect
    from PySide.QtUiTools import QUiLoader
    #from PySide.QtGui import QApplication, QMainWindow, QMessageBox, QFileDialog ,QTableView, QColor, QPalette, QFont, QStyledItemDelegate, QPushButton, QLineEdit, QItemDelegate, QStyleOptionButton, QStyle
    from PySide.QtSql import QSqlQueryModel,QSqlDatabase,QSqlQuery, QSqlTableModel
     
    from PySide.QtCore import *
    from PySide.QtGui import *
     
    print ("PySide.__version__ = %s" %PySide.__version__)
    print ("PySide.QtCore.__version__ = %s" % PySide.QtCore.__version__ )
    print ("PySide.QtCore.qVersion() = %s" % PySide.QtCore.qVersion())
     
     
    SCRIPT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
     
     
    class UiLoader(QUiLoader):
        """
        Subclass :class:`~PySide.QtUiTools.QUiLoader` to create the user interface
        in a base instance.
        Unlike :class:`~PySide.QtUiTools.QUiLoader` itself this class does not
        create a new instance of the top-level widget, but creates the user
        interface in an existing instance of the top-level class.
        This mimics the behaviour of :func:`PyQt4.uic.loadUi`.
        """
     
        def __init__(self, baseinstance, customWidgets=None):
            """
            Create a loader for the given ``baseinstance``.
            The user interface is created in ``baseinstance``, which must be an
            instance of the top-level class in the user interface to load, or a
            subclass thereof.
            ``customWidgets`` is a dictionary mapping from class name to class object
            for widgets that you've promoted in the Qt Designer interface. Usually,
            this should be done by calling registerCustomWidget on the QUiLoader, but
            with PySide 1.1.2 on Ubuntu 12.04 x86_64 this causes a segfault.
            ``parent`` is the parent object of this loader.
            """
     
            QUiLoader.__init__(self, baseinstance)
            self.baseinstance = baseinstance
            self.customWidgets = customWidgets
     
        def createWidget(self, class_name, parent=None, name=''):
            """
            Function that is called for each widget defined in ui file,
            overridden here to populate baseinstance instead.
            """
     
            if parent is None and self.baseinstance:
                # supposed to create the top-level widget, return the base instance
                # instead
                return self.baseinstance
     
            else:
                if class_name in self.availableWidgets():
                    # create a new widget for child widgets
                    widget = QUiLoader.createWidget(self, class_name, parent, name)
     
                else:
                    # if not in the list of availableWidgets, must be a custom widget
                    # this will raise KeyError if the user has not supplied the
                    # relevant class_name in the dictionary, or TypeError, if
                    # customWidgets is None
                    try:
                        widget = self.customWidgets[class_name](parent)
     
                    except (TypeError, KeyError) as e:
                        raise Exception('No custom widget ' + class_name + ' found in customWidgets param of UiLoader __init__.')
     
                if self.baseinstance:
                    # set an attribute for the new child widget on the base
                    # instance, just like PyQt4.uic.loadUi does.
                    setattr(self.baseinstance, name, widget)
     
                    # this outputs the various widget names, e.g.
                    # sampleGraphicsView, dockWidget, samplesTableView etc.
                    #print(name)
     
                return widget
     
     
    def loadUi(uifile, baseinstance=None, customWidgets=None,
               workingDirectory=None):
        """
        Dynamically load a user interface from the given ``uifile``.
        ``uifile`` is a string containing a file name of the UI file to load.
        If ``baseinstance`` is ``None``, the a new instance of the top-level widget
        will be created.  Otherwise, the user interface is created within the given
        ``baseinstance``.  In this case ``baseinstance`` must be an instance of the
        top-level widget class in the UI file to load, or a subclass thereof.  In
        other words, if you've created a ``QMainWindow`` interface in the designer,
        ``baseinstance`` must be a ``QMainWindow`` or a subclass thereof, too.  You
        cannot load a ``QMainWindow`` UI file with a plain
        :class:`~PySide.QtGui.QWidget` as ``baseinstance``.
        ``customWidgets`` is a dictionary mapping from class name to class object
        for widgets that you've promoted in the Qt Designer interface. Usually,
        this should be done by calling registerCustomWidget on the QUiLoader, but
        with PySide 1.1.2 on Ubuntu 12.04 x86_64 this causes a segfault.
        :method:`~PySide.QtCore.QMetaObject.connectSlotsByName()` is called on the
        created user interface, so you can implemented your slots according to its
        conventions in your widget class.
        Return ``baseinstance``, if ``baseinstance`` is not ``None``.  Otherwise
        return the newly created instance of the user interface.
        """
     
        loader = UiLoader(baseinstance, customWidgets)
     
        if workingDirectory is not None:
            loader.setWorkingDirectory(workingDirectory)
     
        widget = loader.load(uifile)
        QMetaObject.connectSlotsByName(widget)
        return widget
     
     
    class MonDelegate(QStyledItemDelegate):
     
        def __init__(self,parent = None):
            super(MonDelegate, self).__init__(parent)
            self._parent = parent
            self.liste_index=[]
     
        def paint(self, painter, option, index):
     
    ##        print (type(index))
            value= index.data(Qt.DisplayRole)
    ##        print ("index.data(Qt.DisplayRole):=%s" % value)
    ##        print ("type(value)=%s" % type(value))
    ##        print ("type(str(value))=%s" % type(unicode(value)))
    ##        print ("(str(value))=%s" % (unicode(value)))
     
            painter.save() 
            rect=QRect(option.rect)
            c=QColor()
            c=Qt.red
     
            if ([index.column(), index.row()]) in self.liste_index:
                 painter.fillRect(rect, c)
            value= unicode(index.data(Qt.DisplayRole))
     
            #painter.drawText(option.rect, Qt.AlignLeft, value)
            painter.restore()
     
            super(MonDelegate, self).paint(painter, option, index)
     
     
     
     
    ##    def setEditorData(self, editor, index):
    ##        QStyledItemDelegate.setEditorData(self, editor, index)
     
        def setModelData(self, editor, model, index):
            self.addlistindex(index)
            print("*********************************************")
            print ("type(editor)=%s" % type(editor))
            print("*********************************************")
            #model.setData(index, editor.currentText(), QtCore.Qt.DisplayRole)
            super(MonDelegate, self).setModelData(editor, model, index)
     
     
     
        def addlistindex(self, index):
     
            alist=[]
            alist.append(index.column())
            alist.append(index.row())
            print (alist)
            self.liste_index.append(alist)
     
        def razlistindex(self):
     
            self.liste_index=[]    
     
     
    class CustomSqlModel(QSqlTableModel):
        def data(self, index, role):
            if ((role == Qt.FontRole) and index.column()==0):
                boldFont=QFont()
                boldFont.setBold(True)
                return boldFont
     
     
            return super(QSqlTableModel, self ).data(index, role);
     
     
     
     
     
    class MainWindow(QMainWindow):
     
        def __init__(self, parent=None):
            QMainWindow.__init__(self, parent)
            loadUi(os.path.join(SCRIPT_DIRECTORY, 'forms/myform.ui'), self)
            self.comboBox_liste_tables.setEnabled(False)
     
     
        @Slot()
        def on_MenuOpen_triggered(self):
     
     
           path, _ = QFileDialog.getOpenFileName(self, "Open File sqlite ", os.getcwd(), ("Sqlite Files (*.sqlite *.db )") )
           self.label.setText(path)
           self.label_2.setText(_)
           self.db = QSqlDatabase.addDatabase("QSQLITE")
           self.db.setDatabaseName(path)
           self.db.open()
           liste_tables=(QSqlDatabase.tables(self.db))
           #self.projectModel = QSqlTableModel(self, self.db);
           self.projectModel = CustomSqlModel(self, self.db)
     
           self.projectModel.setEditStrategy(QSqlTableModel.OnManualSubmit);
           self.projectModel.select(); 
           ##print (liste_tables)
           for  text in liste_tables:
               if text !='sqlite_sequence':
                   self.comboBox_liste_tables.addItem( text)
     
           self.comboBox_liste_tables.setEnabled(True)           
     
     
           #self.projectModel = QSqlQueryModel()
           #self.projectModel.setQuery("select * from process where 1",self.db)
     
     
     
           self.tableWidget_sqlite.setModel(self.projectModel)
           self.tableWidget_sqlite.setItemDelegate(MonDelegate(self.tableWidget_sqlite))
           self.tableWidget_sqlite.setStyleSheet("selection-background-color: blue")
           #self.tableWidget.setModel(self.projectModel)
     
     
        @Slot()
        def on_MenuQuit_triggered(self):
           self.close() 
     
        @Slot()
        def on_comboBox_liste_tables_currentIndexChanged(self):
            print ("change index")
            print (self.comboBox_liste_tables.currentText())
            #self.projectModel.setQuery("select * from %s where 1" % self.comboBox_liste_tables.currentText(),self.db)
            self.projectModel.setTable("%s" % self.comboBox_liste_tables.currentText())
            self.projectModel.select();
     
            self.tableWidget_sqlite.setModel(self.projectModel)
            self.tableWidget_sqlite.setVisible(False)
            self.tableWidget_sqlite.resizeColumnsToContents()
            self.tableWidget_sqlite.setVisible(True)
            #self.tableWidget.setModel(self.projectModel)
        @Slot()
        def on_tableWidget_sqlite_clicked(self):
            pass
            #self.tableWidget_sqlite.item(0,0).setBackgroundColor(Qt.red)
     
        @Slot()
        def on_save_button_clicked(self):
            self.projectModel.submitAll()
            self.tableWidget_sqlite.itemDelegate().razlistindex()
     
     
     
     
    def main():
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        app.exec_()
     
     
    if __name__ == '__main__':
        main()
    et l'ui:
    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
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>1094</width>
        <height>713</height>
       </rect>
      </property>
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>849</height>
       </size>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QGridLayout" name="gridLayout">
        <property name="leftMargin">
         <number>10</number>
        </property>
        <property name="topMargin">
         <number>10</number>
        </property>
        <property name="rightMargin">
         <number>10</number>
        </property>
        <property name="bottomMargin">
         <number>10</number>
        </property>
        <property name="spacing">
         <number>5</number>
        </property>
        <item row="0" column="0">
         <layout class="QGridLayout" name="gridLayout_2">
          <property name="sizeConstraint">
           <enum>QLayout::SetMaximumSize</enum>
          </property>
          <item row="0" column="0">
           <layout class="QGridLayout" name="gridLayout_3">
            <item row="1" column="0">
             <widget class="QComboBox" name="comboBox_liste_tables">
              <property name="enabled">
               <bool>true</bool>
              </property>
             </widget>
            </item>
            <item row="0" column="0">
             <layout class="QHBoxLayout" name="horizontalLayout_4">
              <item>
               <widget class="QPushButton" name="pushButton_4">
                <property name="text">
                 <string>PushButton</string>
                </property>
               </widget>
              </item>
              <item>
               <widget class="QPushButton" name="save_button">
                <property name="text">
                 <string>Save</string>
                </property>
               </widget>
              </item>
              <item>
               <spacer name="horizontalSpacer">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>40</width>
                  <height>20</height>
                 </size>
                </property>
               </spacer>
              </item>
             </layout>
            </item>
            <item row="1" column="1">
             <spacer name="horizontalSpacer_2">
              <property name="orientation">
               <enum>Qt::Horizontal</enum>
              </property>
              <property name="sizeType">
               <enum>QSizePolicy::Expanding</enum>
              </property>
              <property name="sizeHint" stdset="0">
               <size>
                <width>70</width>
                <height>20</height>
               </size>
              </property>
             </spacer>
            </item>
           </layout>
          </item>
          <item row="1" column="0">
           <widget class="QTableView" name="tableWidget_sqlite">
            <property name="cursor" stdset="0">
             <cursorShape>OpenHandCursor</cursorShape>
            </property>
            <property name="dragEnabled">
             <bool>true</bool>
            </property>
            <property name="selectionMode">
             <enum>QAbstractItemView::SingleSelection</enum>
            </property>
            <property name="gridStyle">
             <enum>Qt::NoPen</enum>
            </property>
           </widget>
          </item>
         </layout>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="label_2">
          <property name="layoutDirection">
           <enum>Qt::LeftToRight</enum>
          </property>
          <property name="text">
           <string/>
          </property>
         </widget>
        </item>
        <item row="1" column="0">
         <widget class="QLabel" name="label">
          <property name="text">
           <string/>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>1094</width>
         <height>21</height>
        </rect>
       </property>
       <widget class="QMenu" name="menuFichier">
        <property name="title">
         <string>File</string>
        </property>
        <addaction name="MenuOpen"/>
        <addaction name="MenuClose"/>
        <addaction name="MenuQuit"/>
       </widget>
       <addaction name="menuFichier"/>
      </widget>
      <action name="MenuOpen">
       <property name="checkable">
        <bool>false</bool>
       </property>
       <property name="text">
        <string>Open</string>
       </property>
      </action>
      <action name="MenuClose">
       <property name="text">
        <string>Close</string>
       </property>
      </action>
      <action name="MenuQuit">
       <property name="text">
        <string>Quit</string>
       </property>
      </action>
     </widget>
      <connections/>
     <slots>
      <slot>on_actionHello_clicked()</slot>
      <slot>on_clickMe_clicked(bool)</slot>
      <slot>on_MenuOuvrir_clicked()</slot>
     </slots>
    </ui>
    Merci beaucoup pour votre aide.

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 480
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    J'ai fait un truc comme ça qui marche très bien et qui est très puissant! Mais comme je suis en Python 3 et PyQt5, il est possible que mes apports ne soient pas adaptés. Essayons quand même.

    J'ai donc un QTableView qui affiche une table d'une base de données sqlite3, avec un modèle QSqlRelationalTableModel. Cela suffit en général pour afficher et modifier des données de la table.

    Comme c'est un pilote relationnel, il suffit de déclarer les contraintes de clés étrangères pour que l'affichage du QTreeView en tienne compte. En particulier par le remplacement d'une case de type QLineEdit par une case de type QComboBox. Ainsi, les modifications de cette case sont strictement limitées aux valeurs prévues par la contrainte: impressionnant...

    J'utilise le mode OnManualSubmit, ce qui veut dire que j'ai besoin de faire quelque chose (bouton, item de menu) pour que les modifications que j'ai faites soient enregistrées dans la base.

    Mais comme j'ai voulu couvrir des besoins plus larges, j'ai ajouté 2 choses:

    - un delegate (QSqlRelationalDelegate) me permettant d'utiliser d'autres widgets que ceux prévus par défaut. Je préfère, par exemple, utiliser un QLineEdit avec completion plutôt qu'un QComboBox pour les données avec contraintes de clés étrangères.

    - un QSortFilterProxyModel me permettant d'ajouter plusieurs fonctions perso de recherches/filtrages, y compris une fonction de recherche de mots similaires qui me permet de retrouver facilement des noms mal saisis au clavier.

    En ce qui concerne le delegate (QSqlRelationalDelegate):

    - la méthode createEditor est exécutée à la création de l'affichage. C'est là qu'on définit les widgets à utiliser pour certains colonnes et/ou certains types de données.

    - la méthode setEditorData est exécutée à chaque fois qu'on accède au mode d'édition de la case. On rentre dans le mode édition quand on tape une lettre ou qu'on double clique sur la case

    - la méthode setModelData est exécutée à chaque fois qu'on quitte le mode d'édition, et qu'il faut définir comment on enregistre les valeurs modifiées dans le modèle. On quitte le mode édition avec un retour chariot, une tabulation ou un clic de souris dans une autre case.

    Je sais qu'on peut surcharger aussi la méthode paint, mais je n'en ai pas eu besoin jusqu'à présent.

    Quand on doit changer quelque chose dans le comportement du QTableView par rapport au modèle, et en particulier quand on utilise d'autres widgets que ceux prévus à l'origine, on surcharge les 3 méthodes.

    Pour prendre un petit exemple simple, on peut faire en sorte que le passage en mode édition change la couleur de la case, qui revient à la couleur normale en fin d'édition.

    C'est puissant, ça marche bien, mais je n'ai pas dit que c'était facile...

    Si ce que je viens de dire te convient, tu peux poser des questions plus précises.

  3. #3
    Membre à l'essai
    Inscrit en
    Octobre 2009
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 24
    Points : 18
    Points
    18
    Par défaut
    Alors comment dire: UN GRAND MERCI !!!
    J'ai pris le temps d'ingurgiter tout ce que tu viens de m'expliquer tyrtamos.
    Après vint le we et d'autres projets...
    Je m'y suis remis en remplaçant simplement QSqlTableModel par QSqlRelationalTableModel et là oh miracle ça marche.
    Quand j'édite une cellule, celle-ci devient rouge une fois modifiée et lors de l'appui sur le bouton "save" les cellules redeviennent transparentes.
    J'ai plein de docs encore à lire... car il faut que je rajoute des fonctionnalités.
    En gros la partie édition de la base semble fonctionner même s'il faut que je rajoute des 'validator'.
    Là où ça va se corser, c'est qu'il faut maintenant que je compare la base avec des données contenues dans un automate programmable et trouver le moyen d'afficher les différences dans la vue utilisée pour l'édition.
    Je ne manquerai pas si je sèche et vu mes très petites connaissances en qt de te contacter.
    Merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Problème de mise à jour d'une base de données avec php
    Par cykablue dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/02/2011, 16h46
  2. [FORMS6] : mise à jour d'une vue
    Par gaultier dans le forum Forms
    Réponses: 13
    Dernier message: 03/07/2006, 12h15
  3. Mise à jour d'une table avec une autre
    Par Lucien dans le forum SQL
    Réponses: 2
    Dernier message: 20/04/2006, 10h46
  4. [MySQL] Problème de mise à jour d'une table
    Par SnickeursMan dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 17/01/2006, 11h39
  5. Mise à jour d'une table avec un fichier csv
    Par blackangel dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 26/05/2005, 14h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo