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 :

bug avec pyinstaller (bug styleSheet?)


Sujet :

PyQt Python

  1. #1
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut bug avec pyinstaller (bug styleSheet?)
    Bonjour, j'ai remarqué un bug assez étrange:
    Voici un code minimal:

    Code test.py : 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
    from PyQt5 import QtWidgets, QtCore, QtGui
    import sys
     
     
    app = QtWidgets.QApplication(sys.argv)
    with open('test.css') as f:
    	app.setStyleSheet(f.read())
    w = QtWidgets.QDialog()
    c1 = QtWidgets.QComboBox()
    c1.addItems(list('azertyuiop'))
     
    c2 = QtWidgets.QComboBox()
    c2.addItems(list('azertyuiop'))
     
    layout = QtWidgets.QVBoxLayout(w)
    layout.addWidget(c1)
    layout.addWidget(c2)
     
    w.show()
    app.exec_()

    Code test.css : 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
    QComboBox {
    	color: deepskyblue;
    	selection-background-color: deepskyblue;
    	background-color: #f2fcff;
    	border: 1px solid #1e1e1e;
    	border-radius: 5;
    	font: 75 11pt "Tahoma";
    	width: 14em;
    	height: 1.3em;
    }
     
    QComboBox:hover {
    	border: 2px solid deepskyblue;
    }
     
    QComboBox:on {
    	padding-top: 3px;
    	padding-left: 4px;
    	background-color: #eeeeee;
    }
     
    QComboBox::drop-down {
    	subcontrol-origin: padding;
    	subcontrol-position: top right;
    	width: 15px;
    	border-left-width: 0px;
    	border-left-color: darkgray;
    	border-left-style: solid;
    	border-top-right-radius: 3px;
    	border-bottom-right-radius: 3px;
    }
     
    QComboBox::down-arrow {
    	image: url(styleSheet/Sky/down_arrow.png);
    }
     
    QComboBox QAbstractItemView {
    	border: 2px solid darkgray;
    	color: deepskyblue;
    	background-color: #eeeeee;
    	selection-color: black;
    	selection-background-color: deepskyblue;
    }
    Avec pyinstaller les items dans les combobox sont invisibles quand ils ont le focus ...
    (avec tab c'est bien flagrant)

    Une piste ?
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Comme "test.css" est une donnée pour pyinstaller, il faut 2 choses:

    1- le faire recopier pendant le traitement avec dans la ligne de commande:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    --add-data ".\test.css;."
    2- permettre au programme traité de retrouver "test.css" avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import os
     
    if getattr(sys, 'frozen', False):
    	REPEXE = sys._MEIPASS # programme traité par pyinstaller
    else:
    	REPEXE = os.path.dirname(os.path.abspath(__file__)) # prog. normal
     
    css = os.path.join(REPEXE, 'test.css')
    A voir avec l'image que j'ai supprimée dans mon essai parce que je ne l'avais pas.

    Moyennant quoi, ça marche!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    Merci mais en faites c'est pas ici que ça coince, aucun soucis pour ça, il est graphique.
    Quelques screen du problème (fais à l'arrache):
    Nom : Sans titre.png
Affichages : 369
Taille : 13,0 Ko
    à gauche le code source, à droite le .exe
    quand j'ai le focus sur le code source aucun soucis sur les combobox, mais quand j'ai le focus sur le .exe là si le widget qui à le focus est un combobox alors il se "vide" (juste visuellement)... c'est d'ailleurs bien parlant en spammant tab, le focus switch entre chaque combobox et donc ils disparaissent et réapparaisse de façon épileptique.

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Dans mes essais, tant pour le traitement "onefile" que pour le traitement "onedir", je constate un comportement identique des combobox avec la solution normale Python.

    La version onefile de mes essais est ici: http://infos.jpvweb.com/forum/test.zip. Je le laisse 24h.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    Vraiment bizarre, tu à pourtant utilisé le même code source ? avec le même styleSheet ?
    J'ai ce problème en utilisant pyinstaller -w -F test.py ou pyinstaller test.spec.
    J'utilise pyinstaller 3.3.1 / PyQt 5.10.1 et python 3.6.1 , je sais pas si sa joue mais vraiment la bizarre.
    Franchement je sais pas d'où se peut venir là ...

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    J'utilise actuellement Python 3.5 et PyQt5 5.9.

    Après mon essai précédent, je me suis procuré un 'down_arrow.png' de 16x16 (ici: https://findicons.com/icon/181791/arrow_medium_down) pour le mettre dans les combobox.

    Comme pour test.css, il faut demander à pyinstaller de le recopier avec --add-data, mais ça ne suffit pas puisqu'avec le traitement onefile, le répertoire d'exécution n'est pas connu avant l'exécution elle-même. Il faut donc "injecter" la bonne adresse dans le texte du css avant sa prise en compte dans le setStyleSheet.

    Voilà ce que j'ai utilisé:

    test.css => seule modif dans le "QComboBox::down-arrow":

    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
    QComboBox {
    	color: deepskyblue;
    	selection-background-color: deepskyblue;
    	background-color: #f2fcff;
    	border: 1px solid #1e1e1e;
    	border-radius: 5;
    	font: 75 11pt "Tahoma";
    	width: 14em;
    	height: 1.3em;
    }
     
    QComboBox:hover {
    	border: 2px solid deepskyblue;
    }
     
    QComboBox:on {
    	padding-top: 3px;
    	padding-left: 4px;
    	background-color: #eeeeee;
    }
     
    QComboBox::drop-down {
    	subcontrol-origin: padding;
    	subcontrol-position: top right;
    	width: 15px;
    	border-left-width: 0px;
    	border-left-color: darkgray;
    	border-left-style: solid;
    	border-top-right-radius: 3px;
    	border-bottom-right-radius: 3px;
    }
     
    QComboBox::down-arrow {
        image: url(%s);
    }
     
    QComboBox QAbstractItemView {
    	border: 2px solid darkgray;
    	color: deepskyblue;
    	background-color: #eeeeee;
    	selection-color: black;
    	selection-background-color: deepskyblue;
    }
    test.py:

    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
    # -*- coding: utf-8 -*-
    # Python v3.5 PyQt5 v5.9
     
    from PyQt5 import QtWidgets, QtCore, QtGui
    import sys
    import os
     
    if getattr(sys, 'frozen', False):
    	REPEXE = sys._MEIPASS # programme traité par pyinstaller
    else:
    	REPEXE = os.path.dirname(os.path.abspath(__file__)) # prog. normal
    css = os.path.join(REPEXE, 'test.css')
    png = os.path.join(REPEXE, 'down_arrow.png').replace('\\', '/')
     
    app = QtWidgets.QApplication(sys.argv)
     
    with open(css) as f:
    	textecss = f.read() % png # <= injection de la bonne adresse de l'image png
    	app.setStyleSheet(textecss)
     
    w = QtWidgets.QDialog()
     
    c1 = QtWidgets.QComboBox()
    c1.addItems(list('azertyuiop'))
     
    c2 = QtWidgets.QComboBox()
    c2.addItems(list('azertyuiop'))
     
    layout = QtWidgets.QVBoxLayout()
    layout.addWidget(c1)
    layout.addWidget(c2)
    w.setLayout(layout)
     
    w.show()
    sys.exit(app.exec_())
    Pour la ligne de commande de pyinstaller avec Windows, j'utilise un fichier bat:

    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
    SET programme=test
     
    IF EXIST build_onefile RMDIR /S /Q build_onefile
    IF EXIST dist_onefile RMDIR /S /Q dist_onefile
     
    pyinstaller.exe ^
    --clean ^
    --noconfirm ^
    --noconsole ^
    --onefile ^
    --noupx ^
    --distpath ".\dist_onefile" ^
    --workpath ".\build_onefile" ^
    --add-data ".\test.css;." ^
    --add-data ".\down_arrow.png;." ^
    %programme%.py
    PAUSE
    Le fait de changer les "distpath" et "workpath" me permet d'avoir les 2 versions "onefile" et "onedir" séparées (sinon, la dernière version remplace la précédente).

    J'ai mis la nouvelle version "onefile" test.zip avec la petite flèche dans les combobox à la même adresse web que précédemment.

    Avec ça, tout se passe bien chez moi!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    Bonjour,
    J'ai cherché à éliminer tous les facteurs possibles qui pourrait engendrer ce bug, oui car c'est bien un bug je ne voit pas d'autre explication...
    J'ai pourtant un système similaire au tien (inclusion de fichier, utilisation de sys._MEIPASS si code freezé, un moyen de gérer les url des stylesheets, ect... )

    Voici l'exemple le plus minimal que je puisse faire pour obtenir se bug... ça vient de ça : "border: 1px solid #1e1e1e;"

    Code test.py : 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
    from PyQt5 import QtWidgets
    import sys
     
    a = []
    for i in range(5):
    	a.append('azerty')
     
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QDialog()
     
    c1 = QtWidgets.QComboBox()
    c1.addItems(a)
    c1.setStyleSheet("""border: 1px solid #1e1e1e;""")
     
    c2 = QtWidgets.QComboBox()
    c2.addItems(a)
    c2.setStyleSheet("""border: 1px solid #1e1e1e;""")
     
    c3 = QtWidgets.QComboBox()
    c3.addItems(a)
    # c3.setStyleSheet("""border: 1px solid #1e1e1e;""")
     
    c4 = QtWidgets.QComboBox()
    c4.addItems(a)
    # c4.setStyleSheet("""border: 1px solid #1e1e1e;""")
     
    layout = QtWidgets.QVBoxLayout(w)
    layout.addWidget(c1)
    layout.addWidget(c2)
    layout.addWidget(c3)
    layout.addWidget(c4)
     
    w.show()
    app.exec_()

    J'utilise juste pyinstaller -w -F test.py pour se test (mais pour mon vrai programme pyinstaller prog.spec, avec le fichier spec qui gère l'inclusion des fichiers/dossiers)

    Code prog.spec : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ...
    a = Analysis(
    	...
    	...
    	datas=[
                       ('icon', 'icon'),
                       ('styleSheet', 'styleSheet'),
    	],
    	...
    	...
    )
    ...

    voici le code source et le code freezé que j'ai obtenue : https://www.dropbox.com/s/0a5vcewy1z6j0gg/test.zip?dl=0

    Mystère et boule de gomme ..

  8. #8
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Est-que tu as au moins essayé d'appliquer l'intégralité du source (sans modification) que je t'ai donné? Ceci pour tester les différences éventuelles de version et d'installation.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  9. #9
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    J'avais également test mais non...
    Je vais tenter d'installer python et tout le reste sur un pc virtuel pour voir se que ça donne ..
    J'espère que c'est un bug qui c'est glissé avec Qt 5.10, sinon je vais passer de bon moment à chercher le pourquoi du comment :'(


    Sinon je n'est pas bien compris le % png, enfin l'intérêt pour moi, mon logiciel a plusieurs thèmes sélectionnables, avec plein d'image je me voit mal faire ça pour chaque fichier.. Dans mon cas je met juste url(chemin relatif) dans mon stylesheet et quand je le lit je remplace sont url relatif par absolu.

    ça donne quelque chose de moins jolie mais ça marche impec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if getattr(sys, 'frozen', False):
    	base_path = sys._MEIPASS
    else:
    	base_path = os.path.dirname(os.path.abspath(__file__))
     
    ...
     
    with open(os.path.join(base_path, "styleSheet", setting['thème'], setting['thème']+'.css'), 'r', encoding='utf-8') as CSS:
    	app.setStyleSheet(CSS.read().replace('url(', 'url(' + base_path + '/').replace('\\', '/'))

  10. #10
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    Up, même problème sous une autre machine .. et j'ai downgrade vers PyQt5.9 .. Et bien ça marche enfin !

    Si quelqu'un peut adapter et tester mon exemple en C++, savoir si sa via de Qt ou du binding PyQt.. je voudrait pas ouvrir un rapport de bug à la mauvaise personne

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Comme j'étais intrigué par ton pb, j'ai un peu creusé.

    Je suis passé à PyQt5 v5.10 => j'ai le même problème que toi: le combobox qui a le focus n'affiche pas le texte sélectionné (mais affiche quand même la petite flèche) dans les 2 exe résultats du traitement pyinstaller (onefile et onedir). Mais ça marche correctement avec l'exécution .py normale (sans pyinstaller).

    J'ai cherché en ajoutant plusieurs instructions du combobox, mais je n'ai pas trouvé de solution.

    Par contre, ça marche sans le setStyleSheet! Alors, j'ai utilisé une "bête" copie de l'exemple donné sur le site Qt5: http://doc.qt.io/qt-5/stylesheet-examples.html. Non seulement ça marche dans tous les cas, mais c'est loin d'être moche ;-) .

    Conclusion: travaille ton css!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

Discussions similaires

  1. Margin top bug entre IE et Firefox
    Par jeff24 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 26/08/2009, 14h51
  2. Bug entre navigateurs
    Par tiesto95 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 18/02/2009, 10h37
  3. Bug entre valeur de parametre
    Par Jerez62 dans le forum IHM
    Réponses: 1
    Dernier message: 26/06/2008, 11h45
  4. Bug entre IE et FireFox
    Par ultrasrouche dans le forum Webdesign & Ergonomie
    Réponses: 1
    Dernier message: 19/07/2007, 23h34
  5. Bug entre le bootloader et mon kernel ?
    Par hudson dans le forum Programmation d'OS
    Réponses: 13
    Dernier message: 21/06/2005, 13h40

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