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

Python Discussion :

Python création d'un fichier PDF : impossible de créer 2 pdf avec la même instance


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 5
    Par défaut Python création d'un fichier PDF : impossible de créer 2 pdf avec la même instance
    Bonjour
    J'apprends le dév avec Python. J'ai créé un outil avec interface graphique en tkinter. Cela me permet de générer des demandes de réparation pour une société de maintenance avec un QRCODE et un document récapitulant les éléments de la demande pour le technicien. Une fois la demande remplie, j'enregistre le fichier en pdf.
    J'arrive à faire cela. Cependant, dès lors que j'ouvre une deuxième demande de réparation depuis ma page principale, au moment de valider l'enregistrement j'ai ceci comme erreur :

    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
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "/usr/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
        return self.func(*args)
      File "/home/xxx/Documents/python/travail-python/reptravail/di2.py", line 492, in valider
        recup_valeur()
      File "/home/xxx/Documents/python/travail-python/reptravail/di2.py", line 473, in recup_valeur
        creerpdf.genererpdf (originefinal, sitefinal, unitefinal, entreeUnfinal, entreeDeuxfinal, entreeTroisfinal, codematfinal, quantitefinal, entreeCinqfinal, remarquefinal)
      File "/home/xxx/Documents/python/travail-python/reptravail/creerpdf.py", line 178, in genererpdf
        pdf.save()
      File "/home/xxx/.local/lib/python3.8/site-packages/reportlab/pdfgen/canvas.py", line 1244, in save
        self._doc.SaveToFile(self._filename, self)
      File "/home/xxx/.local/lib/python3.8/site-packages/reportlab/pdfbase/pdfdoc.py", line 207, in SaveToFile
        raise RuntimeError("class %s instances can only be saved once" % self.__class__.__name__)
    RuntimeError: class PDFDocument instances can only be saved once
    J'ai lu le code de reportab et je comprends que je ne peux pas générer 2 fichiers PDF avec la même instance tkinter.
    J'ai pourtant ma demande qui, une fois rappelée, est vide.

    La seule solution est de fermer complètement mon programme. Ce n'est pas pratique si on a plusieurs demandes à faire.
    Si quelqu'un aurait une solution pour vider l'instance tkinter.

    Je précise que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pdf.showPage()  
        pdf.save()
    sont bien présents mais cela ne marche pas. Il me semblait que pdf.showPage() réinitialisait la page.

    Merci pour votre aide, car là je cale

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Sans code, pas vraiment facile de t'aider. Je suis donc allé chercher un code d'exemple.

    Voici le code d'origine...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from reportlab.pdfgen import canvas
    c = canvas.Canvas("hello.pdf")
    c.drawString(100, 750, "Welcome to Reportlab!")
    c.save()
    ... auquel je rajoute un second c.save(). Effectivement même plantage que pour toi.

    Maintenant, j'écris ceci

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from reportlab.pdfgen import canvas
     
    def genere(name):
    	c = canvas.Canvas(name)
    	c.drawString(100, 750, "Welcome to Reportlab!")
    	c.save()
    # genere()
     
    genere("a.pdf")
    genere("b.pdf")
    genere("a.pdf")
    Et là, plus de souci. Peut-être donc que ta solution est là. A chaque nouvelle demande, tu réinitialises entièrement la chaine de création...
    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
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 5
    Par défaut Complément d'information
    Bonjour

    Le code est disponible.
    Je rappelle mon problème de génération de 2 fichiers pdf dans la même instance.
    Autre problème que je viens de voir c'est lorsque je valide la demande, j'ai une boîte de dialogue qui apparaît. Si je clique sur annuler j'ai une erreur. Je souhaiterais simplement que la boîte de dialogue se ferme et revienne sur la DI, à défaut au menu principale.


    voici comment est articulé le mien
    J'ai un fichier qui gère une fenêtre principale qui permet d'ouvrir un fichier d'aide, et une demande d'intervention et quitter le programme.
    J'ai un fichier qui gère la demande d'intervention avec les éléments comme le produit, la date, le modif etc.. Lorsque je valide ma demande,
    je viens récupérer tous mes arguments que je transmets à un 3ème fichier qui lui gère mon traitement PDF.
    Pour l'enregistrement, j'ouvre une boîte de dialogue afin d'enregistrer mon fichier sur un répertoire du choix de l'utilisateur et le nom qu'il souhaite donner.
    Là, une fois enregistré le document, la fenêtre demande intervention se ferme. Je retombe dans ma première fenêtre principale. Lorsque je veux recréer une deuxième demande, ma fenêtre s'ouvre, mais je ne peux pas générer le PDF et ma boîte de dialogue me permettant l'enregistrement ne s'ouvre pas.

    Merci encore de ton aide
    Fichiers attachés Fichiers attachés

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par laminux Voir le message
    Le code est disponible.
    Mouais, je viens de voir. Toutefois t'as dû faire de grosses modifs par rapport à ma première intervention puisque (j'ai testé) on ne peut pas générer 2 fois un pdf.
    Je pense que c'est dans le source "creerpdf.py" ligne 66 où tu écris pdf = canvas.Canvas(nomfichier) en variable globale (en dehors de toute fonction). Ce qui correspond à mon premier exemple. Comme ledit source n'est importé qu'une fois, le pdf n'est pas réinitialisé.
    Ce qui m'amène d'ailleurs à remarquer qu'en fait, tu ne t'appuies pas du tout sur l'encapsulation des fonctions. Tu mets tout en vrac dans tes divers sources. Ce qui fait que ledit vrac est exécuté non pas quand tu cliques sur un bouton (lequel bouton pourrait être connecté à une fonction) mais quand le source est importé (donc pour ainsi dire quand on appelle le main.py).
    Exemple: un source "toto.py"...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #!/usr/bin/env python3
    #coding: utf-8
    print("Hello World from toto")

    ... et un source "titi.py"
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #!/usr/bin/env python3
    #coding: utf-8
    def action(): print("Hello World from titi")

    Et un import direct des deux sources
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> from toto import *
    Hello World from toto
    >>> from titi import *
    >>> 2+3
    5
    >>> 5-2
    3
    >>> action()
    Hello World from titi
    Tu vois la différence ??? L'import du second source m'offre un affichage tout aussi con que le premier, sauf que cet affichage c'est moi qui décide quand l'invoquer.

    Citation Envoyé par laminux Voir le message
    Autre problème que je viens de voir c'est lorsque je valide la demande, j'ai une boîte de dialogue qui apparaît. Si je clique sur annuler j'ai une erreur. Je souhaiterais simplement que la boîte de dialogue se ferme et revienne sur la DI, à défaut au menu principale.
    Ben en ligne 42 quand tu récupères le nom du fichier nomfichier = tkinter.filedialog.asksaveasfilename( title="Enregistrer sous ...", filetypes=[('Fichier PDF','.pdf')]) ce nom est vide quand tu cliques sur "annuler". Donc là encore si tu avais encapsulé tes actions dans des fonctions tu pourrais tester si le nom est vide tu quittes la fonction. Malheureusement tel que c'est écrit, tu peux soit tester "si le nom est vide alors exit()" et tu quittes le programme, ou alors n'exécuter ce qui se trouve en dessous que si le nom n'est pas vide.
    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]

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 5
    Par défaut Génération pdf
    Bonsoir
    Merci d'avoir pris le temps de lire le code. Alors oui il n'est certainement pas dans les règles de l'art. Maintenant je débute en python et fais de mon mieux.
    Je vais voir pour encapsuler mon code dans plus de fonctions.
    Voire des classes si cela est utile 🤔

    Je reviendrai sur le, forum pour donner des nouvelles si je m'en sort.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 5
    Par défaut résolution
    Bonjour Sve@r
    çà y est tout fonctionne. J'ai vu où étaient mes erreurs. Il y avait un problème avec les variables globales et locales, notamment pour la création de mon canvas. Effectivement, il était créé de façon globale alors qu'il faut le créer dans ma fonction.
    Pour mon problème de boîte de dialogue, avec un coup de debug on comprend mieux le cheminement du programme. J'ai simplement testé si le nom de mon fichier était vide ou pas.
    Merci d'avoir pris le temps de lire le code et surtout d'avoir abordé la notion de variables globales.

    affaire résolue
    bonne continuation

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 827
    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 827
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par laminux Voir le message
    Merci d'avoir pris le temps de lire le code et surtout d'avoir abordé la notion de variables globales.
    Il serait utile que tu lises quelques tutos...

    Citation Envoyé par laminux Voir le message
    affaire résolue
    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]

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

Discussions similaires

  1. [XL-2007] Création d'un fichier PDF avec signets
    Par Philippe Lachenal dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 03/05/2012, 12h23
  2. [FPDF] Création d'un fichier PDF avec un tableau
    Par pascale86 dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 16/11/2010, 11h56
  3. création d'un fichier pdf avec php
    Par crati dans le forum Langage
    Réponses: 3
    Dernier message: 12/03/2009, 10h55
  4. création d'un fichier pdf avec iText et jsf
    Par paolo2002 dans le forum JSF
    Réponses: 9
    Dernier message: 08/12/2008, 13h54
  5. création d'un fichier pdf avec iText et jsf
    Par paolo2002 dans le forum Documents
    Réponses: 1
    Dernier message: 25/06/2008, 10h10

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