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 :

QPixmap: It is not safe to use pixmaps outside the GUI thread


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 197
    Par défaut QPixmap: It is not safe to use pixmaps outside the GUI thread
    Bonjour

    pour notre service commercial, j'ai pondu un script qui permet de générer des tarifs clients en pdf à partir de renseignements contenus dans un fichier ini.

    Lancé seul ce script fonctionne très bien, c'est basé sur les fonctionnalités de QPrinter.

    J' amène une évolution:
    J'ai une fenêtre dans laquelle il y' a une table où j'utilise un thread qui parcourt les fichiers ini et affiche ligne/ligne l'évolution de la génération des tarifs.
    Le soucis est que les pdfs sont bien générés mais il n'y a pas les images qu'il devrait y avoir dedans..
    Dans ma classe de génération, j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.painter.drawPixmap(10*mm,10*mm,QPixmap(os.path.dirname(__file__)+"\\png\\logojpg"))
    La console est remplie de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QPixmap: It is not safe to use pixmaps outside the GUI thread
    Sur le net on en parle mais je comprends pas grand chose, on parle d'utiliser qImage mais je m'en sors pas..
    Avez vous des pistes?

    [Windows7, Python 2.7]

    Merci

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

    La raison est simple: on ne doit pas toucher directement au graphique dans les threads. C'est souvent le cas des bibliothèques graphiques (non "thread-safe").

    La solution est relativement facile à mettre en oeuvre: utiliser QThread comme thread, et organiser l'échange de messages (emit / connect) entre le thread et la partie principale du programme. Par exemple, si le thread veut imprimer, il envoie le message donnant l'ordre, et c'est le GUI qui imprime. Une fois qu'on a compris, c'est assez simple à faire, et ça marche très bien.

    Si tu as besoin de plus, je peux te faire un petit exemple.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 197
    Par défaut
    Merci pour ton aide.

    Au niveau du QThread, tu m'avais déjà aidé dans un précèdent post

    voici le code simplifié au maximum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
     
     
    class GenePDF:
      def __init__(self,ficIni):
        self.loadIni()
     
      def loadIni(self): # recuperation des infos dans fichier ini
        self.client = ...
        self.date   = ...
     
      def genere(self): # impression
        self.printer = QPrinter(QPrinter.HighResolution)
        self.printer.setOutputFormat(QPrinter.PdfFormat)
        self.painter = QPainter(self.printer)
        ...
        self.painter.drawPixmap(10*mm,10*mm,QPixmap('logo.png'))
        ...
        self.painter.end()
     
     
    class ThreadIni(QtCore.QThread): # Thread qui liste les fichiers ini d'un dossier et appelle la classe pour generer pdf..
      def __init__(self, parent=None):
        super(ThreadIni, self).__init__(parent)
        self.parent = parent
     
      def run(self):
        list_ini = os.listdir(DOSINI)
        nb_row = 0
        for fic_ini in list_ini:
          if fic_ini[-3:] <> 'INI': continue
          f_ini = GenePDF(fic_ini)
          f_ini.genere()
          self.emit(QtCore.SIGNAL("ajoutLigne(PyQt_PyObject)"), [nb_row, f_ini.client,...])
          nb_row +=1
     
     
    class Fen(QtGui.QWidget): # Fenetre affiche évolution de la génèrations des pdfs..
      def __init__(self, parent=None):
          super(Fen, self).__init__(parent)
          self.setLayout(QtGui.QGridLayout())
          self.butPdf = QtGui.QPushButton("PDF")
          self.butPDF.clicked.connect(self.clickPDF) 
          self.table = QtGui.QTableWidget()
          self.layout().addWidget(self.butPdf,0,0)
          self.layout().addWidget(self.table,1,0)
     
      def clickPDF(self):
        self.table.clear()
        self.table.setRowCount(0)
        t = ThreadIni(self)
        self.connect(t, QtCore.SIGNAL("ajoutLigne(PyQt_PyObject)"), self.ajoutLigne)
        t.start()
     
      def ajoutLigne(self,obj):
        nb_row = obj[0]
        self.table.insertRow(nb_row)
        it_cli = QtGui.QTableWidgetItem(obj[1].title())
        ...

    Appelé indépendamment, la classe GenePDF génère bien mes pdfs..
    par contre, avec l'affichage de la fenêtre, ca se génère mais sans les images..

    le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.painter.drawPixmap(10*mm,10*mm,QPixmap('logo.png'))
    génère dans la console : QPixmap: It is not safe to use pixmaps outside the GUI thread

    J'iamgine que je dois repenser ma classe GenePDF mais pour le moment je vois pas trop comment..

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2009
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2009
    Messages : 197
    Par défaut
    bon j'ai une solution, après quelques recherches, j'ai vu qu'il était conseillé d'utiliser plutôt QImage.
    j'ai donc remplacé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.painter.drawPixmap(10*mm,10*mm,QPixmap('logo.png'))
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    self.painter.drawImage(QPoint(10*mm,10*mm),QImage('logo.png'))
    et ca fonctionne

    Merci pour ta sollicitude Tyrtamos (sympa tes tutos, ca dépanne bien)

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Bizarre qu'un tel changement ait pu résoudre ton problème, mais tant mieux si ça marche. Méfie-toi tout de même que ça ne coince pas "de temps en temps"...

    Citation Envoyé par Nico_tournai Voir le message
    Merci pour ta sollicitude Tyrtamos (sympa tes tutos, ca dépanne bien)
    Ça, ça fait plaisir, merci. Mais j'ai un "kolossal" retard dans mes tutos...

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Oui, c'est le "f_ini = GenePDF(fic_ini)" dans le thread qui ne va pas, quand il initialise le printer: il faut réorganiser ton code.

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

Discussions similaires

  1. [Lazarus] [Ubuntu] Erreur "Can not find CairoCanvas used by OSPrinters"
    Par ChPr dans le forum Lazarus
    Réponses: 3
    Dernier message: 11/09/2014, 22h51
  2. Réponses: 16
    Dernier message: 26/07/2011, 17h07
  3. The component 'xyz' does not have a resource identified by the URI
    Par ptitshrek dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 05/02/2010, 16h48

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