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 :

Ubuntu Desktop File


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Animateur Numérique
    Inscrit en
    Février 2013
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Animateur Numérique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2013
    Messages : 142
    Par défaut Ubuntu Desktop File
    Salut,

    Rien de bien mirobolant, juste une appli python qui permet de créer des fichiers .desktop pour Linux (Ubuntu).

    Le git est là :

    https://github.com/diablo76600/Ubuntu-Desktop-File

  2. #2
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    bonjour

    coté "linux":

    Pourquoi cette liste de catégorie pas standard ?
    La liste officielle est ici et à noter que TextEditor n'est qu'une des nombreuses sous-catégories.

    Pourquoi parler de ubuntu ?
    Ces fichiers sont un standard freedesktop respecté par les bureaux.
    Pourquoi écrire un outil en QT alors que ubuntu est gtk (normalement) ? Pour kde ok, mais pour gnome (comme son nom et l'icône l'indique), cela me parait absurde. Mais, ok si c'est pour tout bureau

    Choix de l'icône :
    Avoir la possibilité de piocher dans le thème actif me semble un minimum !

    Lanceur de cette application:
    Pourquoi créer un script bash alors qu'il suffit de mettre un shebang à ton fichier main.py ?


    --------------

    Coté python je n'ai pas regardé en profondeur, juste très surpris de trouver un fichier "model.py" sans le "modèle" des datas de ce fichier.
    En fait, tu n'utilises même pas un modèle Du coup, le métier est complètement imbriqué dans la Gui et ce qui entraine que je n'ai même pas envie de lire le code.

    Dans le dialogue de sauvegarde, tu pourrais ajouter filter = "Application file (*.desktop)"

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Une critique (un conseil): par exemple sur cette fonction (au hasard)...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def display_message(title: str, text: str, type_message: str) -> None:
    	"""Display a message box with the specified title, text, and type."""
    	if type_message == "warning":
    		QMessageBox.warning(None, title, text)
    	else:
    		QMessageBox.information(None, title, text)
    ... pourquoi définir le type de façon textuelle ? C'est tout sauf efficace. Analyser une chaine c'est loooong (relativement aux comparaisons numériques je veux dire). Surtout qu'en plus Qt offre déjà les constantes existantes !!! Pourquoi en redéfinir d'autres qui seront au mieux inutiles ?

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def display_message(title: str, text: str, type_message=QMessageBox.Information: int) -> None:
    	"""Display a message box with the specified title, text, and type."""
    	match type_message:
    		case QMessageBox.Warning: box=QMessageBox.warning
    		case QMessageBox.Information: box=QMessageBox.information
    	# match
    	box(None, title, text)
    Et à l'appel, tu lui passes au choix QMessageBox.Warning ou QMessageBox.Information. Ou (à voir) un autre flag permettant d'afficher un autre type de messageBox (fonction alors à faire évoluer ce qui est assez facile dans la structure match...)

    Autre chose: hériter de Qt c'est bien... mais cela ne doit pas faire perdre les avantages des objets d'origine (autrement dit, on préserve les objets et tous leurs paramètres). Surtout...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class UbuntuDesktopFileCategoriesView(QDialog):
        """Manage the Ubuntu Desktop File Categories View."""
        def __init__(self, *args, **kwargs) -> None:
            super().__init__(*args, **kwargs)
    ...que ce n'est franchement pas super compliqué...
    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]

  4. #4
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    Analyser une chaine c'est loooong
    Il ne faut pas exagérer ! L'application ne va certainement pas afficher 1000 erreurs en même temps.
    mais: je suis tout a fait raccord avec la modification !

    @Diablo76
    En programmation, il est classique de remplacer les constantes chaines (dupliquées) par des constantes numériques :
    - moins de place en mémoire
    - plus rapide ...
    - surtout pas de risque d'erreur (en gros, tu as presque écrit : getattr(QMessageBox, type_message)(None, title, text))

    ps: voir, parfois, si besoin, remplacer par des constantes de type enum

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Le "côté obscur" n'est pas plus fort, mais il requiert une discipline et une vision à long terme pour résister à ses tentations.
    Les bénéfices d'une architecture propre et d'une conception réfléchie surpassent largement les facilités de développement à court terme.

    Le "côté obscur" (opter pour la facilité et la rapidité à court terme) peut sembler attrayant, mais il conduit souvent à une dette technique accrue et à des difficultés lorsqu'il s'agit d'adapter ou d'étendre l'application.

  6. #6
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    Note sur les model Qt : ce ne sont que des interfaces entre un widget et des datas ! Nous pouvons donc avoir des datas indépendantes de l'interface et suivre facilement le paradigme de fred1599 (à cette étape)

    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
    @dataclass
    class Person:
        nom: str
        age: int
     
    class Metier:
        def __init__(self):
            self._datas = {}
        def retourne(self, index):
            return self._datas[index]
        def change(self, index, person):
            if person.age < 18:
                raise Exception("règle métier")
            self._datas[index] = person
        def count(self):
            return len(self._datas)
     
    class personnes_model(QtCore.QAbstractListModel, database_connecteur="'il vient de la gui ? non"):
        def __init__(self, parent=None):
            super().__init__(parent)
            self._datas = Metier(database_connecteur)
     
        def rowCount(self, parent=QtCore.QModelIndex()):
            return self._datas.count()
     
        def data(self, index, role):
            if role == QtCore.Qt.DisplayRole:
                return self._datas.retourne(index.row()).nom
            if role == QtCore.Qt.UserRole + 666:   # vouloir l'objet dans la GUI ? c'est le diable (si il est mutable)
                return self._datas.retourne(index.row())
     
        def addRow(self, name, age):
            self._datas.ajout(Person(name, age))
     
        def removeRow(self, index):
            pass
    ps: ne pas chercher ici une logique métier ou pythonnesque à la classe Métier

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Je n'ai fais qu'un projet professionnel en PyQt, autant dire que je ne suis pas expérimenté avec... Je ne vais pas avoir une critique sur l'utilisation de Qt !
    Une de mes erreurs (en ce qui me concerne, car l'entreprise ne voit pas le mal) avaient été de rendre ce projet totalement dépendant de PyQt.

    Imaginons, que je veuille passer de PyQt à wxPython ou à Kivy ? Est-ce que tout mon code est bon à mettre à la poubelle ? Sur mon projet, oui !

    C'est pour cela que maintenant dans tous mes projets je fais une fixette sur l'architecture du projet, c'est pour moi un temps que je ne négocie jamais avec mes chefs... L'objectif est de permettre d'ajouter du code, et de ne jamais en supprimer (évolution permanente).

    Si ça vous intéresse, je vous propose de lire ce blog qui parle de la "clean architecture" d'Uncle Bob, tout est indépendant (si je veux passer de SQL à NoSQL par ex., ça doit être possible sans rien supprimer de l'existant SQL) !
    J'ai bien évidemment le bouquin qui est je dois dire complexe à lire (pas parce-qu'il est en anglais, mais un peu vaste, on s'attend à plus de précision).

    C'est très appréciable de se dire que ses projets persistent dans le temps, et à vrai dire aux nombres importants de projets que j'ai pu lire, très rarement je rencontre ce type d'architecture (rencontré 1x dans ma carrière).

    Et perso, comme Sve@r, l'IHM n'est que Vue ! Mais cela implique de nombreux découpage de modules, une organisation plus complexe au départ, mais avec de nombreux avantages par la suite, comme par exemple la simplification des tests unitaires, une évolution rapide du projet, etc.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Une de mes erreurs (en ce qui me concerne, car l'entreprise ne voit pas le mal) avaient été de rendre ce projet totalement dépendant de PyQt.
    Imaginons, que je veuille passer de PyQt à wxPython ou à Kivy ? Est-ce que tout mon code est bon à mettre à la poubelle ? Sur mon projet, oui !

    Et perso, comme Sve@r, l'IHM n'est que Vue ! Mais cela implique de nombreux découpage de modules, une organisation plus complexe au départ, mais avec de nombreux avantages par la suite, comme par exemple la simplification des tests unitaires, une évolution rapide du projet, etc.
    Et hélas c'est le cas de beaucoup. Parce qu'entre écrire directement son select truc from machin dans le widget Qt qui va afficher les datas ou créer la classe modele.select qui va se charger de récupérer les datas en cohérence avec le vrai MVC les sirènes de la tentation et de la facilité font malheureusement que...
    Certes dans mes projets mes tables sont toutes gérées par un objet dédié qui contient les méthodes "update" et "delete" mais pour le select... Je pense que le vrai et pur MVC, celui qui permet de changer facilement et immédiatement X par Y est une utopie.
    - est-ce que le côté obscur est le plus fort ?
    - non ! seulement plus facile, plus rapide, plus séduisant le côté obscur est.
    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 fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Hello,

    Pour display_message,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def display_message(title: str, text: str, type_message: str) -> None:
        """Display a message box with the specified title, text, and type."""
        getattr(QMessageBox, type_message)(None, title, text)
    ça ne fonctionnerait pas ? Car type_message ne semble pas optionnel... la doc me semble pas vraiment utile pour ce genre de méthode, son nom se suffit à elle même.
    Mais au final, la question à se poser, c'est qui gagne-t-on comparé à l'utilisation directe de QMessageBox.warning ou QMessageBox.information ?

    La structure du projet n'est pas très harmonieuse, mais au final on s'en fou un peu... parce-que c'est un petit projet, et que la maintenabilité est simple et qu'on s'y retrouve sans trop de difficulté.
    Et je suis d'accord avec @papajoker, attention aux noms que l'on veut donner surtout quand on veut y apporter un sens, un modèle ou "domain" correspond généralement a la définition des entités métier...

    L'esthétisme est bon, si c'est fonctionnel c'est top ! Mais on va pas se leurrer, ce code ne grossissant pas dans le futur, j'ai pas grand chose à en dire, sinon que l'essentiel est là, ça fonctionne !

    EDIT :

    Sve@r,

    Autre chose: hériter de Qt c'est bien... mais cela ne doit pas faire perdre les avantages des objets d'origine (autrement dit, on préserve les objets et tous leurs paramètres)
    Je ne suis pas sûr de comprendre cette phrase, n'est-ce pas l'appel standard d'une fonction ou d'une méthode avec des arguments optionnels (sans les spécifier à nouveau) ?
    Pour démontrer,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Test:
        def __init__(self, parent=None, x=5):  # Même configuration que l'initialisation de QDialog (2 args optionnels)
            self.parent = parent
            self.x = x
     
     
    class NewTest(Test):
        def __init__(self, *args, **kwargs):
            super().__init__()
     
     
    nt = NewTest(2, 3, a=5, d="z")
    print(nt.parent)  # None
    print(nt.x)  # 5
    Je conserve bien tous les attributs de ma classe mère...
    Mais peut-être n'ai je pas compris où tu voulais en venir avec cette remarque ?

  10. #10
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    pas grand chose à en dire, sinon que l'essentiel est là, ça fonctionne !
    En fait, il nous manque une info ! Quelle est la logique derrière ce code ?
    Si le but est juste qu'il fonctionne, alors ok pour le code
    Si le but est de faire un "template" de bon code (je soupçonne avec les noms controleur et modele), alors c'est loupé.

    - Qt a son propre système mvc (pour ce strict besoin, pas trop utile ici)
    - Bloquer la taille des fenêtres et en plus, tu places les composants de façon statique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    pushButton_quit.setGeometry(QRect(758, 352, 68, 32))
    utton_y = 168
    self.gridLayoutWidget.setGeometry(QRect(8, 8, 585, 165))
    QRect(int((self.width() / 2) - 34), 352, 68, 32)
    self.label_icon_application.setGeometry(QRect(758, 274, 68, 68))
    Et même si on fixe la taille de l'application/dialogues, dans tous les cas, on place/taille les composants relativement, par rapport au conteneur. On peut attribuer des marges si c'est cela qui te pose problème.

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Mais peut-être n'ai je pas compris où tu voulais en venir avec cette remarque ?
    Si tu crées un objet qui hérite d'un QDialog (ou de tout autre objet), ce que tu crées doit à minima offrir les mêmes possibilités que l'objet hérité (sinon on ne fait pas d'héritage). Prenons ton Test et NewTest, tu dois pouvoir utiliser NewTest au-moins exactement comme Test (ce qu'il fait en plus ne doit pas enlever ce que fait "Test").
    Et justement ton NewTest tel que tu l'as écrit (avec *args et **kwargs) offre la possibilité de l'appeler comme Test et ça c'est bon. Mais si tu enlèves *args et **kwargs, tu es alors obligé de lui mettre des paramètres à l'image de ceux de Test (ce qui freine alors son évolutivité).

    Evidemment (tout avantage amène souvent un inconvénient en retour) cela offre la possibilité d'appeler NewTest avec des paramètres non prévus comme dans ton exemple NewTest(2, 3, a=5, d="z"). Dans ce cas c'est Test qui doit checker et refuser "a" et "d" (comme le fera QDialog si tu l'appelles avec des paramètres non attendus).
    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 fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Et justement ton NewTest tel que tu l'as écrit (avec *args et **kwargs) offre la possibilité de l'appeler comme Test et ça c'est bon. Mais si tu enlèves *args et **kwargs, tu es alors obligé de lui mettre des paramètres à l'image de ceux de Test (ce qui freine alors son évolutivité).
    Mais on est bien d'accord que QDialog ne prend pas comme argument *args et **kwargs comme paramètres d'initialisation mais deux paramètres nommés et optionnels qui sont parent et f (flag) ?

    Evidemment (tout avantage amène souvent un inconvénient en retour) cela offre la possibilité d'appeler NewTest avec des paramètres non prévus comme dans ton exemple NewTest(2, 3, a=5, d="z"). Dans ce cas c'est Test qui doit checker et refuser "a" et "d" (comme le fera QDialog si tu l'appelles avec des paramètres non attendus).
    Pour aller plus loin dans mon code, voilà ce que je peux être amené à faire sans perdre ni attribut ni méthode de Test.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class NewTest(Test):
        def __init__(self, *args, **kwargs):
            super().__init__()
            self.arguments = args
            self.dictionary = kwargs
     
     
    nt = NewTest(2, 3, a=5, d="z")
    print(nt.parent)  # None
    print(nt.x)  # 5
    print(nt.arguments)  # (2, 3)
    print(nt.dictionary)  # {'a': 5, 'd': 'z'}


    Si le but est de faire un "template" de bon code (je soupçonne avec les noms controleur et modele), alors c'est loupé.
    Effectivement les termes sont mal choisis, et peut-être qu'il en ressort une incompréhension.

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Mais on est bien d'accord que QDialog ne prend pas comme argument *args et **kwargs comme paramètres d'initialisation mais deux paramètres nommés et optionnels qui sont parent et f (flag) ?
    Tout à fait d'accord. *args et **kwargs tu le mets dans ton objet (d'ailleurs tu ne les as pas mis dans "Test" mais dans "NewTest" et ma toute première remarque s'appliquait à l'objet "UbuntuDesktopFileCategoriesView" de Diablo76) afin que l'utilisateur de ton objet puisse l'appeler avec les paramètres attendus par QDialog (pour avoir depuis ton objet le comportement de QDialog qu'il est en droit d'espérer).
    Et c'est la magie de Python (ou plutôt l'unpacking) qui fait que puisque QDialog attend un paramètre "parent", si tu appelles UbuntuDesktopFileCategoriesView avec un paramètre "parent" ce paramètre sera transmis tel quel à QDialog. Et si tu ne le mets pas (effectivement c'est optionnel) ben il n'y aura pas de paramètre "parent" transmis.
    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]

  14. #14
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Salut !

    @papajoker,

    J'avoue ne pas avoir tout compris et savoir où tu voulais en venir avec ce code... est-ce que te concernant tu lies ce code a ce qui a été dit dans ma précédente conversation ?

    Je l'ai testé avec PyQt6 n'ayant pas PySide6, cependant je ne vois pas concrètement ce que tu souhaites souligner, ni ce que techniquement on doit en retenir... Imaginons que tu expliques à un dev junior ce code, que doit-il en retenir et quelle expérience souhaite tu lui faire partager ? En plus, me concernant je suis une bille en Qt

  15. #15
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    Ce code était uniquement la suite du message #25 : juste un code fonctionnel
    ps: ne pas tenir compte que tout est dans le même fichier c'est uniquement par facilité pour ce forum

    Je viens de voir ton code Arborescence…
    Et je me rends compte que nous avons une vue sur QT complètement différente (Et donc ton bon exemple sur l'autre sujet ne me convient pas du tout).

    Les models QT :

    Pour moi, il est incompréhensible de s'en passer (sauf GUI extrêmement simple)

    Exemple:
    si j'utilise un modelQt, tout mes widgets attachés a lui vont être actualisés en temps réel
    - si j'ai dans ma barre d'outil générale un filtre, l'autocomplétion va s'adapter dès que l'utilisateur ajoute un enregistrement (par exemple un filtre sur "ville"). Même chose si j'ai un combobox
    Donc, avec un modèle, toutes les vues attachés sont mises à jour automatiquement au moindre changement.

    Exemple:
    Si j'utilise un modelQt, nous avons les proxy (datas aussi en temps réel). Un proxy peut servir pour un filtre, mais aussi pour fournir un "nouveau" modèle qui lui aussi est lié à notre modelQT de base

    Exemple:
    - Parfois, pour la gestion fine de l'affichage d'une cellule, nous avons QStyledItemDelegate qui reçoit un item(gui) lié à notre modèleQt
    - avec un QItemDelegate (.setModelData exemples) particulier, je vais pouvoir lier notre modelQT à ce délégé pour un comboBox; exemple: delégé ne retourne qu'une seule colonne et affichée différemment pour ce combo: un combo (temps-réel) avec "ville+cp" tirés de notre modèle


    Puisque je dois absolument utiliser les modelQT, si je veux avoir quand même un modèle python plus classique (utilisable en tests), j'ai donné une recette ici. Et ce modèle (classique*) python à la particularité d'envoyer des messages à la gui lors de modification (pas un refresh de la vue mais uniquement de la cellule)
    *"classique" : pas vraiment dans ce cas car le cahier des charges du départ n'est pas classique (un seul enregistrement), j'ai juste voulu faire simple (minimum de lignes pour ce fichier) et relativement général (manque ajout et suppression)

    Citation Envoyé par fred1599 Voir le message
    Je l'ai testé avec PyQt6 n'ayant pas PySide6
    Comme indiqué plus haut #21, pyside est la lib officielle de la société qui fournit QT. Je ne vois pas l'intérêt d'utiliser une lib non officielle
    ps: ok, cela n'a que quelques années, mais en dev les choses évoluent, avant pyside était le vilain petit canard et pyqt la seule solution.

  16. #16
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Ok je vois que tu es embêté avec le *args et **kwargs, je le retire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class NewTest(Test):
        def __init__(self):
            super().__init__()
            self.arguments = (2, 3)
            self.dictionary = {'a': 5, 'd': 'z'}
     
     
    nt = NewTest()
    print(nt.parent)  # None
    print(nt.x)  # 5
    print(nt.arguments)  # (2, 3)
     
    print(nt.dictionary)  # {'a': 5, 'd': 'z'}
    On est bien d'accord que NewTest a un intérêt en y ajoutant des attributs comme il a pu être fait sur la UbuntuDesktopFileCategoriesView ?
    Note que Test prend la même configuration qu'un QDialog

  17. #17
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    je comprends Sve@r , c'est simplement le O du principe SOLID
    une entité applicative (classe, fonction, module ...) doit être fermée à la modification directe mais ouverte à l'extension
    Mais, ici dans cette appplication, je ne vois pas l'intéret :
    - c'est une classe finale
    - cette classe ne sera jamais surchargée
    - surtout, cette classe n'est utilisée que par un seul appel (je suppose donc que le dev a déjà passé tous ces bons paramètres). Et à la limite, si il désire changer un truc, c'est exactement le même travail de modification dans main ou le fichier de cette classe.
    Si la classe était utilisée plusieurs fois et peut-être dans un contexte différent, alors oui, il faut l'Ouvrir au maximum.

    Perso ? dans ce code, je ne passerais pas kwargs à cette class CategoriesDialog

    EDIT:
    Citation Envoyé par Sve@r Voir le message
    apprendre des trucs qu'il ne sait pas forcément, et qu'il pourra les appliquer demain dans d'autres objets plus critiques
    Nous sommes bien d'accord, c'est un super principe. Mais le problème ici, c'est que tu n'as pas trop donné de raison. Le faire machinalement peut en être une...

  18. #18
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Citation Envoyé par papajoker
    Comme indiqué plus haut #21, pyside est la lib officielle de la société qui fournit QT. Je ne vois pas l'intérêt d'utiliser une lib non officielle
    C'est juste parce-que j'ai un PyQt6 sous la main, et que je ne souhaitais pas créer un nouvel environnement juste pour installer PySide6.

    Non officielle ou pas, si elle existe c'est pour être utilisée... tout autant que PySide dans le temps où c'était le vilain petit canard.

    Citation Envoyé par papajoker
    Pour moi, il est incompréhensible de s'en passer (sauf GUI extrêmement simple)
    Tu as beaucoup de termes où on sent un manque d'ouverture sur ce qui peut se faire dans le monde informatique ... "je ne vois pas l'intérêt, incompréhensible, je dois absolument"... si je te comprend bien, je jette PyQt6, la clean architecture n'a pas d'intérêt et je dois absolument utiliser les models Qt ?

    Mais je ne comprend pas en quoi cette architecture empêche l'utilisation des models Qt, j'ai dû manquer quelque chose ? Je ne l'ai peut-être pas utiliser dans mon exemple, mais ça ne veut pas dire que je fais le choix de m'en passer dans d'autres cas !

  19. #19
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    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 284
    Par défaut
    Tu as beaucoup de termes où on sent un manque d'ouverture
    N'importe quoi !
    je te dis que mon besoin est très différent du tien ! C'est pourtant clair ! Perso, j'ai besoin des modelQt dans 80% des cas (avec gtk c'est un autre système, les xxStore).
    Donc, je persiste, pour moi, c'est un impératif d'utiliser les modèles natifs qt ou gtk.
    je dois absolument utiliser les models Qt ?
    Pour moi, renier une technologie est un manque d'ouverture ! moi, je dis, que je désire utiliser à mon maximum une techno. (c'est comme dire, je ne veux pas utiliser le css pour du web)
    la clean architecture n'a pas d'intérêt
    Toi, dans ton exemple "clean architecture", tu zappes une technologie, je vais en déduire que tu as un manque d'ouverture ? (bien sûr que non) je peux juste te dire que ton exemple dans cet état ne me convient pas. L'architecture de ton exemple est très très bonne, j'ai dit le contraire ? c'est encore du n'importe quoi.

    si je te comprend bien, je jette PyQt6
    Les 2 sont extrêmement proches en code, je souligne uniquement celle qui est officielle : beaucoup de personnes utilisent pyQt car c'est l'historique (sans connaitre pyside). Puisque tu disais ne pas trop bien connaitre Qt, c'était peut-être une chose que tu ne connaissais pas. ici aussi c'est du n'importe quoi, tu déformes une information en une demande/règle. Je développe encore parfois avec pyQt !
    J'ai parlé plusieurs fois de qml sur ce forum (en bien), tu en déduits que je cherche à l'imposer au détriment de pyqt et pyside ?

  20. #20
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Ok je vois que tu es embêté avec le *args et **kwargs, je le retire
    Ben non, c'est justement la solution la plus efficace (et que je plébiscite) pour conserver l'héritage !!!

    Citation Envoyé par fred1599 Voir le message
    On est bien d'accord que NewTest a un intérêt en y ajoutant des attributs comme il a pu être fait sur la UbuntuDesktopFileCategoriesView ?
    Bien sûr !!! Faire un héritage c'est pour avoir le beurre et l'argent du beurre. Mais il faut tout de même avoir le beurre.

    Prends cet exemple: un objet "vehicule" (qui est présumé provenir d'une lib quelconque donc qui n'est pas de toi)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class vehicule:
    	def __init__(self, vMax):
    		self.vMax=vMax

    Toi ton job est de créer un objet qui va hériter de véhicule (donc rajouter un truc "en plus", on va dire la marque, sans perdre les propriétés du véhicule).
    Solution 1
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class voiture(vehicule):
    	def __init__(self, marque, vMax):
    		super().__init__(vMax)
    		self.marque=marque

    L'utilisateur: vvv=voiture("marqueX", 200)...

    Solution 2
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class voiture(vehicule):
    	def __init__(self, marque, *args, **kwargs):
    		super().__init__(*args, **kwargs)
    		self.marque=marque

    L'utilisateur: vvv=voiture("marqueX", 200)...

    Les deux solutions fonctionnent et sont utilisables de la même façon (y compris si l'objet de base a des paramètres facultatifs).
    Mais la première impose de connaitre l'objet hérité (savoir ce qu'il attend pour reproduire les paramètres attendus dans ton objet). Et n'oublions pas que cet objet peut lui-même hériter d'un objet de plus haut niveau => obligé de tout connaitre pour créer un objet hérité correct.

    Alors que la seconde est souple. Tu n'as pas à te préoccuper de "vehicule", tu lui passes "*args" et "**kwargs" sans te faire de noeud au cerveau et roule (c'est le cas de le dire).
    Et en plus la seconde permet de suivre l'évolution. Si "vehicule" évolue...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class vehicule:
    	def __init__(self, vMin, vMax):
    		self.vMin=vMin
    		self.vMax=vMax
    ... tu n'as pas besoin de modifier ton objet et c'est ça qui est important.

    Citation Envoyé par papajoker Voir le message
    Mais, ici dans cette appplication, je ne vois pas l'intéret...
    Je pars du principe que Diablo76 nous a demandé un avis, qu'il a envie d'apprendre des trucs qu'il ne sait pas forcément, et qu'il pourra les appliquer demain dans d'autres objets plus critiques. Pour résumer c'est juste "pour le principe"
    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]

Discussions similaires

  1. Réponses: 8
    Dernier message: 09/08/2019, 16h57
  2. Installer Safe Client sur système Ubuntu Desktop
    Par bogacidre dans le forum SAGE
    Réponses: 1
    Dernier message: 10/01/2017, 10h24
  3. Monitoring reseaux ubuntu-desktop 12.04
    Par TourePlus dans le forum Linux
    Réponses: 10
    Dernier message: 08/07/2015, 13h40
  4. Réponses: 9
    Dernier message: 20/04/2013, 15h37
  5. Réponses: 3
    Dernier message: 30/12/2010, 23h53

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