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 :

QTableView utiliser des données venant d'une DB


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Fonctionnaire
    Inscrit en
    Août 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Fonctionnaire
    Secteur : Finance

    Informations forums :
    Inscription : Août 2016
    Messages : 28
    Points : 14
    Points
    14
    Par défaut QTableView utiliser des données venant d'une DB
    Bonjour,

    Je débute en Python et donc en PyQt. Je souhaite implémenter un QTableView mais en exploitant des données venant d'une DB. J'ai bien vu sur le net que l'on peut utiliser par exemple QSqlDatabase. Mais le 'problème' est que je renvoie une liste d'objets 'Order'. Et dans ce cas, ça ne fonctionne pas. Quelqu'un à une idée ?

    Merci d'avance.

    Marc

    Code du retour de ma requête sql :
    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
     
    # retourne la liste des 'Orders'
        def loadOrders(self) -> list:
            orders = []
            try:
                connexion = sqlite3.connect("DB/orderManager.db")
                mainCurseur = connexion.cursor()
                mainCurseur.execute("""SELECT o.order_id, o.orderDate, e.employee_id, e.name, c.customer_id, c.lastName, c.firstName, c.phone, q.quotation_id, q.quoteNumber FROM order_ o
                    LEFT JOIN employee e ON o.employee_id=e.employee_id
                    LEFT JOIN customer c ON o.customer_id=c.customer_id
                    LEFT JOIN quotation q ON o.quotation_id=q.quotation_id""")
                for o in mainCurseur:
                    employee = Employee(o[3], o[2])
                    customer = Customer(o[5], o[6], o[7], o[4])
                    quotation = Quotation(o[9], o[8])
                    itemOrderCurseur = connexion.cursor()
                    itemOrderCurseur.execute("""SELECT io.order_id , io.nbrArticles, a.article_id, a.label FROM itemOrder io
                        LEFT JOIN article a ON io.article_id=a.article_id
                        where io.order_id = ?""", (o[0],))
                    itemsOrders = []
                    for io in itemOrderCurseur:
                        article = Article(io[3], io[2])
                        itemOrder = ItemOrder(article, io[1])
                        itemsOrders.append(itemOrder)
                    # order = Order(strptime('%d/%m/%Y', o[1]), itemsOrders, employee, customer, o[0], quotation)
                    order = Order(o[1], itemsOrders, employee, customer, o[0], quotation)
                    orders.append(order)
                itemOrderCurseur.close
                mainCurseur.close()
            except sqlite3.Error as error:
                print("Failed to read data from sqlite table Order :", error)
            finally:
                if connexion:
                    connexion.close()

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Tout d'abord ta tonction ne retourne rien (et donc certainement pas une liste d'objets "order"). Ensuite avoir des variables "order" et "orders" n'aide vraiment pas à la lecture et la compréhension.
    Ensuite tu crées "itemOrderCurseur" dans la boucle (donc à chaque itération) mais tu ne le fermes qu'une fois. Accessoirement ton select trucA puis ensuite select trucB selon les valeurs trouvées dans trucA ça se fait en en une fois via une jointure.
    Maintenant c'est quoi un "Order"? Un truc à toi? Comment Qt saurait alors le traiter? Il te faut trouver une astuce pour "apprendre" à Qt comment lire un Order. Peut-être passer par un QSQLTableModel...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre à l'essai
    Homme Profil pro
    Fonctionnaire
    Inscrit en
    Août 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Fonctionnaire
    Secteur : Finance

    Informations forums :
    Inscription : Août 2016
    Messages : 28
    Points : 14
    Points
    14
    Par défaut
    Sorry, je n'ai pas copié tout le code mais il renvoie bien une liste d'Order. Order (= commande) est une classe ainsi que Employee, Customer, Quotation. De la programmation orientée objet

    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
     
    # retourne la liste des 'Orders'
        def loadOrders(self) -> list:
            orders = []
            try:
                connexion = sqlite3.connect("DB/orderManager.db")
                mainCurseur = connexion.cursor()
                mainCurseur.execute("""SELECT o.order_id, o.orderDate, e.employee_id, e.name, c.customer_id, c.lastName, c.firstName, c.phone, q.quotation_id, q.quoteNumber FROM order_ o
                    LEFT JOIN employee e ON o.employee_id=e.employee_id
                    LEFT JOIN customer c ON o.customer_id=c.customer_id
                    LEFT JOIN quotation q ON o.quotation_id=q.quotation_id""")
                for o in mainCurseur:
                    employee = Employee(o[3], o[2])
                    customer = Customer(o[5], o[6], o[7], o[4])
                    quotation = Quotation(o[9], o[8])
                    itemOrderCurseur = connexion.cursor()
                    itemOrderCurseur.execute("""SELECT io.order_id , io.nbrArticles, a.article_id, a.label FROM itemOrder io
                        LEFT JOIN article a ON io.article_id=a.article_id
                        where io.order_id = ?""", (o[0],))
                    itemsOrders = []
                    for io in itemOrderCurseur:
                        article = Article(io[3], io[2])
                        itemOrder = ItemOrder(article, io[1])
                        itemsOrders.append(itemOrder)
                    # order = Order(strptime('%d/%m/%Y', o[1]), itemsOrders, employee, customer, o[0], quotation)
                    order = Order(o[1], itemsOrders, employee, customer, o[0], quotation)
                    orders.append(order)
                itemOrderCurseur.close
                mainCurseur.close()
            except sqlite3.Error as error:
                print("Failed to read data from sqlite table Order :", error)
            finally:
                if connexion:
                    connexion.close()
            return orders

  4. #4
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 102
    Points : 4 448
    Points
    4 448
    Par défaut
    bonjour
    Citation Envoyé par sportman1969 Voir le message
    Bonjour,
    Mais le 'problème' est que je renvoie une liste d'objets 'Order'. Et dans ce cas, ça ne fonctionne pas. Quelqu'un à une idée ?
    Citation Envoyé par sportman1969
    mais il renvoie bien une liste d'Order.
    Si je comprends bien "ça ne fonctionne pas" ?
    - ton code montré fonctionne bien : retourne la liste des "commandes"

    Si ton problème est d'alimenter un QTableView, alors il faut créer une class depuis QAbstractTableModel qui va contenir tes commandes. Ensuite lier la tableVue à ton Modèle particulier

    note: pas forcément la meilleure structure en particulier si tu as des éditions depuis cette Vue... Comme dit par Sve@r, existe des SqlModel (dérivés de AbstractModel)
    https://doc.qt.io/qtforpython-5/over...ew-programming
    $moi= ( !== ) ? : ;

  5. #5
    Membre à l'essai
    Homme Profil pro
    Fonctionnaire
    Inscrit en
    Août 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Fonctionnaire
    Secteur : Finance

    Informations forums :
    Inscription : Août 2016
    Messages : 28
    Points : 14
    Points
    14
    Par défaut
    Bonjour et merci pour votre aide.
    Oui la méthode loadOrders(self) renvoie bien une liste d'objet 'Order'. Mais le message d'erreur que j'ai est que les objets Order ne sont pas itérables. Si dans la méthode loadOrders je ne renvoie pas d'objet mais seulement les data détenues dans la DB (voir code ci-dessous), dans ce cas, ça fonctionne. Je crée bien une classe depuis QAbstractTableModel mais là, je fais certainement des erreurs. Ce qui explique ma demande d'aide...

    méthode loadOrders 'simplifiée'
    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
     
    def loadOrdersSimple(self) -> list:
            orders = []
            try:
                connexion = sqlite3.connect("DB/orderManager.db")
                mainCurseur = connexion.cursor()
                mainCurseur.execute("""SELECT o.order_id, o.orderDate, e.name, c.lastName, c.firstName, c.phone, q.quoteNumber FROM order_ o
                    LEFT JOIN employee e ON o.employee_id=e.employee_id
                    LEFT JOIN customer c ON o.customer_id=c.customer_id
                    LEFT JOIN quotation q ON o.quotation_id=q.quotation_id""")
                orders = mainCurseur.fetchall()
                mainCurseur.close()
            except sqlite3.Error as error:
                print("Failed to read data from sqlite table Order :", error)
            finally:
                if connexion:
                    connexion.close()
            return orders
    Classe Orders_TableModel
    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
     
    class Orders_TableModel(QAbstractTableModel):
        # def __init__(self, facade, parent=None):
        def __init__(self, parent=None):
            super(QAbstractTableModel, self).__init__()
            self.arrayData = self.loadOrdersSimple() 
     
        def headerData(self, section: int, orientation: Qt.Orientation, role: int):
            if role == Qt.DisplayRole:
                if orientation == Qt.Horizontal:
                    return "Column " + str(section)
                else:
                    return "Row " + str(section)
     
        def rowCount(self, parent):
            return len(self.arrayData)
     
        def columnCount(self, parent):
            return len(self.arrayData[0])
     
        def data(self, index, role):
            if not index.isValid():
                return None
            elif role == Qt.EditRole:
                print("edit mode")
                return None
            elif role != Qt.DisplayRole:
                return None
            return self.arrayData[index.row()][index.column()]
     
    ...

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sportman1969 Voir le message
    Oui la méthode loadOrders(self) renvoie bien une liste d'objet 'Order'. Mais le message d'erreur que j'ai est que les objets Order ne sont pas itérables.
    Première erreur, la méthode super() prend en paramètre le nom de la classe courante, pas celle du parent. Faut remplacer super(QAbstractTableModel, self).__init__() par super(Orders_TableModel, self).__init__(). Et comme le schéma est toujours le même (classe courante, self) on peut alors ne pas le mettre, Python complète les blancs => super().__init__(). Ainsi le nom de l'objet peut évoluer sans que tu aies besoin de réusiner ton code.
    Ensuite effectivement, d'après cette partie de code def columnCount(self, parent): return len(self.arrayData[0]) avec self.arrayData=self.loadOrdersSimple() (donc ta liste d'objets Order) ça signifie que tu considères cette liste comme un tableau 2D. Ou plus précisément, que arrayData[0] (un simple Order donc) est itérable puisque tu demandes un len() dessus.
    Mais pour pouvoir demander len(objet) il faut que l'objet ait implémenté une méthode nommée __len__() sinon tu ne peux pas
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    >>> class toto: pass
    ... 
    >>> class titi:
    ...     def __len__(self): return 123
    ... 
    >>> 
    >>> a=toto()
    >>> len(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'toto' has no len()
    >>> b=titi()
    >>> len(b)
    123
    >>>
    Et accessoirement, si loadOrdersSimple() est une méthode interne à ton objet, alors mets-lui deux underscores devant son nom => def __loadOrdersSimple(self). Et pareil pour arrayData, si c'est un attribut interne de travail, alors on le cache de l'extérieur via les doubles underscores.

    Citation Envoyé par sportman1969 Voir le message
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def headerData(self, section: int, orientation: Qt.Orientation, role: int):
    	if role == Qt.DisplayRole:
    		if orientation == Qt.Horizontal:
    			return "Column " + str(section)
    		else:
    			return "Row " + str(section)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def headerData(self, section: int, orientation: Qt.Orientation, role: int):
    	if role != Qt.DisplayRole: return None
    	return {
    		Qt.Horizontal : "Column ", 
    		Qt.Vertical : "Row ",
    	}.get(orientation, "Unknow") + str(section)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre à l'essai
    Homme Profil pro
    Fonctionnaire
    Inscrit en
    Août 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Fonctionnaire
    Secteur : Finance

    Informations forums :
    Inscription : Août 2016
    Messages : 28
    Points : 14
    Points
    14
    Par défaut
    Pour len(objet), il y a la solution d'implémenter une méthode nommée __len__() dans l'objet mais je peux aussi simplement retourner un entier (puisque je connais le nombre de colonnes qui doit être affichées) dans la méthode def columnCount. Mais mon problème (principal) n'est pas là. Visiblement le fait de vouloir afficher une liste d'objet (Order dans mon cas) dans un QTableView n'est pas si simple ou pas possible !

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sportman1969 Voir le message
    Visiblement le fait de vouloir afficher une liste d'objet (Order dans mon cas) dans un QTableView n'est pas si simple ou pas possible !
    Hé oui. Qt ne sait pas ce qu'est un "Order". Tout ce qu'il sait faire, c'est traiter un tableau2D (ou plus exactement un tableau de tableaux). Le tableau de premier niveau tu l'as déjà (tableau de Order), reste à faire en sorte que Order soit utilisable comme un tableau.

    Partons d'un exemple simple, c'est le meilleur moyen de voir ce qui se passe
    Code python : 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
    import sys
     
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
     
    class myWindow(QMainWindow):
    	def __init__(self, *args, **kwargs):
    		super().__init__(*args, **kwargs)
     
    		# The raw data
    		my_array = self.__loadData()
     
    		# Create the QTableView widget and associate to its model
    		tableModel = myTableModel(my_array, parent=self)
    		tableView = QTableView(parent=self)
    		tableView.setModel(tableModel)
     
    		# Place the QTableView in the central area
    		self.setCentralWidget(tableView)
    	# __init__()
     
    	def __loadData(self):
    		return [['00', '01', '02'], ['10', '11', '12'], ['20', '21', '22']]
    # myWindow
     
    # The table model class
    class myTableModel(QAbstractTableModel):
    	def __init__(self, datain, *args, **kwargs):
    		super().__init__(*args, **kwargs)
    		self.__arraydata = datain
     
    	def rowCount(self, parent):
    		return len(self.__arraydata)
     
    	def columnCount(self, parent):
    		return len(self.__arraydata[0])
     
    	def data(self, index, role):
    		if not index.isValid():
    			return None
    		elif role == Qt.EditRole:
    			print("edit mode")
    			return None
    		elif role != Qt.DisplayRole:
    			return None
    		return self.__arraydata[index.row()][index.column()]
    	# data()
    # myTableModel
     
    if __name__ == "__main__":
    	app = QApplication(sys.argv)
     
    	myWindow = myWindow()
    	myWindow.show()
     
    	sys.exit(app.exec())
    # if
    Dans cet exemple, les datas c'est effectivement un tableau de tableaux (les 00, 01, 02, etc).

    Maintenant, remplaçons par un tableau de Order équivalent. Donc pour que ce soit équivalent, un Order doit être une suite de valeurs (les 00, 01, 02, ...)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Order:
    	def __init__(self, *args):
    		self.__data=args
    # Order
    On l'instancie de cette façon Order(x, y, z, ...) et les x, y, z,... sont stockés dans l'attribut __data sous forme de tableau __data=[x, y, z, ...].

    Et on adapte l'exemple
    Code python : 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
    import sys
     
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
     
    class Order:
    	def __init__(self, *args):
    		self.__data=args
    # Order
     
    class myWindow(QMainWindow):
    	def __init__(self, *args, **kwargs):
    		super().__init__(*args, **kwargs)
     
    		# The raw data
    		my_array = self.__loadData()
     
    		# Create the QTableView widget and associate to its model
    		tableModel = myTableModel(my_array, parent=self)
    		tableView = QTableView(parent=self)
    		tableView.setModel(tableModel)
     
    		# Place the QTableView in the central area
    		self.setCentralWidget(tableView)
    	# __init__()
     
    	def __loadData(self):
    		return [Order("01", "02", "03"), Order("10", "11", "12"), Order("20", "21", "22")]
    # myWindow
     
    # The table model class
    class myTableModel(QAbstractTableModel):
    	def __init__(self, datain, *args, **kwargs):
    		super().__init__(*args, **kwargs)
    		self.__arraydata = datain
     
    	def rowCount(self, parent):
    		return len(self.__arraydata)
     
    	def columnCount(self, parent):
    		return len(self.__arraydata[0])
     
    	def data(self, index, role):
    		if not index.isValid():
    			return None
    		elif role == Qt.EditRole:
    			print("edit mode")
    			return None
    		elif role != Qt.DisplayRole:
    			return None
    		return self.__arraydata[index.row()][index.column()]
    	# data()
    # myTableModel
     
    if __name__ == "__main__":
    	app = QApplication(sys.argv)
     
    	myWindow = myWindow()
    	myWindow.show()
     
    	sys.exit(app.exec())
    # if
    (ayant bien séparé les choses, la seule modification se trouve au final dans la méthode __loadData() qui, au lieu de retourner une liste de listes, retourne une liste de Order).

    Effectivement il y aura deux soucis
    • la méthode columnCount() ne fonctionnera pas car elle demande un len(Order) mais mon objet Order n'a pas de __len__()
    • mon objet Order n'est pas indexable (quand je demande self.__arraydata[x] dans la méthode data() comme si Order était une liste). Il lui faut pour cela la méthode __getitem__() permettant d'adresser mon objet "Order" comme on s'adresse à un iterable


    Ce qui donne ce code adapté
    Code python : 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
    import sys
     
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
     
    class Order:
    	def __init__(self, *args):
    		self.__data=args
     
    	def __len__(self): return len(self.__data)
     
    	def __getitem__(self, index): return self.__data[index]
    # Order
     
    class myWindow(QMainWindow):
    	def __init__(self, *args, **kwargs):
    		super().__init__(*args, **kwargs)
     
    		# The raw data
    		my_array = self.__loadData()
     
    		# Create the QTableView widget and associate to its model
    		tableModel = myTableModel(my_array, parent=self)
    		tableView = QTableView(parent=self)
    		tableView.setModel(tableModel)
     
    		# Place the QTableView in the central area
    		self.setCentralWidget(tableView)
    	# __init__()
     
    	def __loadData(self):
    		return [Order("01", "02", "03"), Order("10", "11", "12"), Order("20", "21", "22")]
    # myWindow
     
    # The table model class
    class myTableModel(QAbstractTableModel):
    	def __init__(self, datain, *args, **kwargs):
    		super().__init__(*args, **kwargs)
    		self.__arraydata = datain
     
    	def rowCount(self, parent):
    		return len(self.__arraydata)
     
    	def columnCount(self, parent):
    		return len(self.__arraydata[0])
     
    	def data(self, index, role):
    		if not index.isValid():
    			return None
    		elif role == Qt.EditRole:
    			print("edit mode")
    			return None
    		elif role != Qt.DisplayRole:
    			return None
    		return self.__arraydata[index.row()][index.column()]
    	# data()
    # myTableModel
     
    if __name__ == "__main__":
    	app = QApplication(sys.argv)
     
    	myWindow = myWindow()
    	myWindow.show()
     
    	sys.exit(app.exec())
    # if

    Et voilà comment j'affiche un tableau de Order dans un QTableView. En faisant en sorte que mon objet Order soit utilisable comme un tableau car Qt ne connait que les tableaux.

    Et s'il faut pouvoir modifier un Order, c'est à dire faire en sorte qu'il accepte l'instruction self.__arraydata[x]=valeur, alors il faut lui rajouter la méthode __setitem__().
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 102
    Points : 4 448
    Points
    4 448
    Par défaut
    En fait, il faudrait comprendre pourquoi tu vas créer un objet "commande" si ce n'est que pour l'utiliser ici ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            return self.arrayData[index.row()][index.column()]
    ok si ton objet "commande" n'était qu'un tuple

    -------

    Pour un objet, c'est à nous de faire une conversion "No de colonne" -> Attribut de l'objet

    par exemple très simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # attribut de classe
    COLONNES = ("reference", "total","client")
     
    def data(self, index, role):
        commande = self.__arraydata[index.row()]
        return getattr(commande, self.COLONNES[index.column()])
    et pour model.columnCount(), il suffit de retourner len(self.COLONNES)

    EDIT: la (big) différence avec Sve@r
    Ici, le modèle est plus indépendant de l'objet "Order" sur un point : Nous pouvons créer 36 modèles dans notre application pour le même objet, suffit de créer des models qui héritent de cette classe et ne changer (presque?) que self.COLONNES
    $moi= ( !== ) ? : ;

  10. #10
    Membre à l'essai
    Homme Profil pro
    Fonctionnaire
    Inscrit en
    Août 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Fonctionnaire
    Secteur : Finance

    Informations forums :
    Inscription : Août 2016
    Messages : 28
    Points : 14
    Points
    14
    Par défaut
    Je comprends bien qu'un Qt ne sait pas ce qu'est un "Order" mais pour faire court, je voulais savoir si on pouvait exploiter un objet dans un QTableView comme le fait le TableView dans JavaFX (https://devstory.net/11079/javafx-tableview).
    Merci d'avoir passé tant de temps à vouloir m'aider...

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par sportman1969 Voir le message
    mais pour faire court, je voulais savoir si on pouvait exploiter un objet dans un QTableView
    Ben oui, à condition de programmer ton objet pour qu'il se comporte comme un tableau, cf mon dernier code !!!!
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 102
    Points : 4 448
    Points
    4 448
    Par défaut
    Citation Envoyé par sportman1969 Voir le message
    comme le fait le TableView dans JavaFX
    Chaque framework est différent, c'est à toi de t'adapter. On te donne 2 solutions et tu doutes encore ???


    Une autre éventuelle solution très simple si ton objet "commande" est complexe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Order:
     
        def to_row(self):
            return (str(self.reference), self.client.name, self.client.ville, self.total)
     
     
    class MonModele:
     
        def data(self, index, role):
            ...
            commande = self.__arraydata[index.row()]
            return commande.to_row()[index.column()]
    mais, comme écrit plus haut, je ne suis pas chaud de modifier la classe des datas (Order) pour l'adapter à un modèle puisque l'on peut avoir plusieurs modèles pour une même classe. (exemple: Ce modèle commandes pour un tableau et un modèle "références" pour un comboBox)
    $moi= ( !== ) ? : ;

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 03/12/2012, 09h34
  2. Réponses: 16
    Dernier message: 04/09/2010, 02h16
  3. [PROC] utiliser des données selectionnées dans une procédure.
    Par ellix86 dans le forum Développement
    Réponses: 5
    Dernier message: 17/04/2009, 13h08
  4. Utilisation Des Données Contenues Dans Une Liste
    Par Sniffle dans le forum Général Python
    Réponses: 6
    Dernier message: 10/03/2009, 16h41
  5. Réponses: 1
    Dernier message: 12/12/2007, 10h35

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