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 :

Problèmes de codage (encore)


Sujet :

Python

  1. #1
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut Problèmes de codage (encore)
    Bonjour à tous,

    Et oui encore un post concernant un problème de codage.
    Je suis sur le PC depuis 8h ce matin et je pense que cela a du me lobotomiser un peu le cerveau.

    Je demande donc un petit coup de main et d'oeil neuf sur le problème suivant.

    Je récupère le contenu d'1 wx.TextCtrl multiligne et souhaite l'afficher dans le un document pdf grâce à Reportlab.

    Dans le contenu de ce wxTextCtrl j'ai évidemment des accents.

    Malgré un grand nombre d'essai je ne parviens pas à éviter le message d'erreur suivant:

    Elements.append(p(u'%s'%com, font('courier', 11, 0, 0)))
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 44: ordinal not in range(128)
    voici les différents essais que j'ai pu faire... ou txt est mon wx.TextCtrl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    !-*- conding:utf-8 -*-
    com = txt.GetValue()
    Elements.append(p(u'%s'%com, font('courier', 11, 0, 0)))
    ### ou
    com = txt.GetValue()
    Elements.append(p(com, font('courier', 11, 0, 0)))
    ### ou
    com = txt.GetValue()
    if not wx.USE_UNICODE:
    com = com.encode("iso8859-15", "replace")
    Elements.append(p(com, font('courier', 11, 0, 0)))
    ### ou
    com = txt.GetValue()
    com = com.encode("cp1252", "replace")
    Elements.append(p(com, font('courier', 11, 0, 0)))
    ### ou
    ...[/CODE]

    Le plus affolant et ce qui me fait complètement tourner la carte (expression de chez moi qui veut dire) c'est que ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    !-*- conding:utf-8 -*-
    com = 'éééééé'
    Elements.append(p(com, font('courier', 11, 0, 0)))
    ça fonctionne nikel...

    J'attends grandement une aide de votre part et aussi... une énième explication.

    merci de votre patience
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  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,

    Sans prétendre maitriser le sujet, je vais essayer d'apporter quelques éléments de réponse. A force de me "cogner" à ce sujet, j'ai fini par trouver quelques recettes qui ont l'air de marcher.

    Mais je ne connais pas suffisamment wx pour savoir en quel encodage il travaille. En tout cas, si tu ne sais pas non plus, il faut chercher, car Python ne devine pas tout. Dans ton premier exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Elements.append(p(u'%s'%com, font('courier', 11, 0, 0)))
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 44: ordinal not in range(128)
    Le 'u' que tu as utilisé oblige Python à convertir la chaine en unicode interne, mais comme tu ne donnes pas l'encodage de cette chaine, il prend par défaut le codec ASCII qui ne supporte pas les caractères accentués. Donc, convertis explicitement ta chaine en unicode avec decode(), en donnant son encodage d'origine. Si c'est l'utf-8, cela donne: com.decode('utf-8')

    - Dans tous les cas, quand Python donne une erreur d'encodage avec le codec ASCII, ça veut dire qu'on l'oblige à faire une conversion sans lui donner les éléments.

    - Ta ligne de coding est bizarre: la bonne ligne est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    # -*- coding:utf-8 -*-
    - Quand on définit une telle ligne, cela suppose que le code source est édité et enregistré avec le même encodage. En cas de doute, vérifie avec un éditeur hexa les octets de ton fichier sur disque. En fait, la ligne coding sert à dire à Python quel est l'encodage du code source, et donc des chaines stockées en dur dans celui-ci. Contrairement à ce qu'on lit ici ou là, ce n'est pas l'encodage par défaut de l'interpréteur (qui se configure différemment), et ça n'a aucun rapport avec l'encodage de la console de sortie (sys.stdout.encoding).

    - Quand dans le code source, une chaine a été définie avec un 'u' devant, elle est transformée en unicode pendant l'exécution, en utilisant bien entendu le coding. En fait, les 2 lignes suivantes sont équivalentes (avec le coding à utf-8), et convertissent toutes les 2 la chaine x (initialement stockée en 'utf-8' dans le fichier source), en unicode interne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    x = u"abcéèçàù"
    x = "abcéèçàù".decode('utf-8')
    - Quand Python parle d'unicode, il parle d'unicode interne et non de n'importe quel unicode! D'après ce que j'ai pu lire ici ou là, ce serait, dans la plupart des implantations de Python, de l'UCS2 qui est une version simplifiée de l'UTF-16 (simplifiée au sens que l'UCS2 a toujours 2 octets, ce qui n'est pas le cas de l'UTF-16). Mais pour Python, une chaine en utf-8 n'est pas en unicode mais en str: type(u"abcéèçàù")=unicode, mais type(u"abcéèçàù".encode('utf-8'))=str.

    - Il est très important de considérer que seul l'unicode interne permet de manipuler les chaines en interne. Pour en être convaincu, il suffit de se livrer à ce petit test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    x = u"abcéèçàù"  # chaine en unicode interne
    print len(x)
    8
     
    x = u"abcéèçàù".encode('utf-8')  # chaine en utf-8
    print len(x)
    13
    Dans cet exemple, Python s'est trompé sur le nombre de caractères de la chaine utf-8.

    - Une fois qu'on a compris ça, on adopte la logique de codage suivante:

    1- il faut convertir le plus tôt possible toutes les chaines entrantes en unicode interne (entrées code source, lecture disque, saisie console, ...)

    2- if faut convertir le plus tard possible toutes les chaines sortantes dans l'encodage voulu (affichage console, écriture disque, ...)

    3- entre les 2, il ne faut travailler qu'en unicode.

    - Pour convertir une chaine d'un encodage à un autre, on passe toujours par l'unicode interne!
    => Pour passer de n'importe quel encodage à l'unicode interne, on utilise decode(encodage_de_la_chaine_à_convertir).
    => Pour passer de l'unicode interne à n'importe quel encodage, on utilise encode(encodage_voulu).

    Dans tes autres exemples, tu cherches à convertir ta chaine com en unicode interne avec encode(), alors que ça devrait être avec decode().

    Regarde si ta méthode font() n'a pas une option encoding.

    Je ne sais pas ce que ta fonction p() est censée faire, mais c'est elle qui semble déclencher le besoin de conversion: à voir de plus près.

    Voilà ce que je peux dire du sujet pour l'instant. J'espère que ça t'éclaire un peu.

    Tyrtamos

  3. #3
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Bonjour et déjà merci pour toutes ces explications.

    J'ai pas encore tout pigé et je pense qu'une bonne relecture au calme un peu plus tard devrait arranger ceci.

    J'ai cependant quelques petites remarques:
    1°) Concernant ma première ligne du script, effectivement je suis allez un peu vite lors de l'écriture et celle qu'il y a dans mon code est bien celle que tu me donnes.

    2°) Concernant le , celui-ci ne m'a pas permis de résoudre mon problème (il m'a même retourner la même erreur qu'avec "ascii"), j'ai donc fouillé encore et encore sur le net et j'ai testé tout ce que je trouvais... au final un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    com.decode(''iso8859-1")
    à l'air de convenir.

    3°) Dans mon code p est défini ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import reportlab.platypus as rpb
    p = rpb.Paragraph
    celle-ci permet de traiter un texte de "x" caractères avec retour à la ligne, ...
    Après quelques recherches et essais, voici ce que j'ai pu avoir comme message d'erreur:
    if type(text) is str: text = text.decode('utf8')
    File "C:\python25\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 0: unexpected end of data
    Ce "if" fait partie du script Paragraph.py, ce qui explique effectivement mon souci.
    J'ai donc dans ce script remplacé cette fonction par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if type(text) is str: 
        try: text = text.decode('utf8')
        except: text = text.decode("iso8859-1")
    et à priori ça marche pas mal.

    Merci encore pour ton aide.

    Bye.

    Jiyuu

    PS: dois-je informer les big boss de reportlab de ma petite modif???

    [EDIT]
    Je viens de faire un essai avec ces caractères:
    é à è ê ï€ @
    le seul qui ne convient pas est €... Celui-ci ressort sous forme d'un carré noir...
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  4. #4
    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
    Citation Envoyé par Jiyuu Voir le message
    le seul qui ne convient pas est €... Celui-ci ressort sous forme d'un carré noir...
    Si tu travailles en iso8859-1, c'est normal. Pour avoir le sigle euro, il faut l'iso8859-15.

    Tyrtamos

  5. #5
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Si tu travailles en iso8859-1, c'est normal. Pour avoir le sigle euro, il faut l'iso8859-15.

    Tyrtamos
    J'ai fait la modif mais à priori ça ne fonctionne pas mieux...

    Je rencontre un autre petit souci plus important que celui-ci (qui ne rentre pas vraiment dans le cadre de ce topic, mais tu pourras peut être m'aider)...

    Comme je l'ai dit plus haut, j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import reportlab.platypus as rpb
    p = rpb.Paragraph
    pour générer des paragraphes dans mon document pdf.
    Le souci c'est que reportlab.platypus.Paragraph gère les sauts de lignes comme un espace et du coup la mise en page obtenue n'est pas vraiment celle souhaitée.

    Une solution assez simple serait de détecter chaque saut de ligne avant d'utiliser reportlab.platypus.Paragraph et de gérer les éléments qu'il y aura entre chaque comme des paragraphes indépendants...

    Vois-tu comment je pourrais faire pour détecter ces sauts?
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  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
    S'il s'agit de détecter les caractères de fin de ligne '\r' et/ou '\n', ça me parait facile et je ne te vois pas poser ce genre de question (mais attention cependant à l'unicode).

    Donc, ça doit être: à quel endroit de la ligne je dois générer un changement de ligne, compte tenu de la police utilisée et de la longueur de l'affichage.

    Si c'est bien ta question: je ne sais pas. Si c'est autre chose, précise!

    Tyrtamos

  7. #7
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    S'il s'agit de détecter les caractères de fin de ligne '\r' et/ou '\n', ça me parait facile et je ne te vois pas poser ce genre de question (mais attention cependant à l'unicode).
    Tyrtamos
    Et bien au risque de passer pour un gros nul, c'est exactement ça.

    Pour rappel, j'écris du texte dans un wx.TextCtrl, multi-ligne et j'aimerai garder la mise en page.
    Il faut donc que je puisse définir facilement à quel endroit ce trouve ces suats de lignes afin de traiter par la suite chaque bloc séparément...

    [EDIT]:
    A titre d'exemple si j'utilise la méthode GetStringSelection() du wx.TextCtrl je ne parviens pas à faire apparaitre (grâce à un print) les caractères de saut de ligne, contrairement à un exemple tiré des démo de la doc wx.Python.
    Ce qui apparait est exactement ce que j'ai dans mon TextCtrl
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Si tu veux afficher une chaîne sans que les whitespace characters soient interprétés :

    les whitespace characters sont [ \t\n\r\f\v]
    http://www.python.org/doc/2.5.4/lib/re-syntax.html

    tu peux utiliser repr()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import urllib
     
    sock = urllib.urlopen('http://system.solaire.free.fr/soleil.htm')
    ch = sock.read(200)
    sock. close()
     
    print repr(ch)
    print '\n===================\n'
    print ch
    affiche
    '<html>\n<head>\n<title>Le Soleil</title>\n<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\n<meta name="keywords" content="syst\xe8me solaire,\nstructure,\ncomposition,\nsoleil,\nprotuber'

    ===================

    <html>
    <head>
    <title>Le Soleil</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="keywords" content="système solaire,
    structure,
    composition,
    soleil,
    protuber

    ou mettre les lignes en liste avec splitlines(True)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import urllib
     
    sock = urllib.urlopen('http://system.solaire.free.fr/soleil.htm')
    ch = sock.read(200)
    sock. close()
     
    li = ch.splitlines(True)
    print li
    print '\n-------------------------------\n'
    print ch
    affiche
    ['<html>\n', '<head>\n', '<title>Le Soleil</title>\n', '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\n', '<meta name="keywords" content="syst\xe8me solaire,\n', 'structure,\n', 'composition,\n', 'soleil,\n', 'protuber']

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

    <html>
    <head>
    <title>Le Soleil</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="keywords" content="système solaire,
    structure,
    composition,
    soleil,
    protuber


    Mais je ne sais pas si c'est vraiment ça qui te manquait

  9. #9
    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
    Citation Envoyé par Jiyuu Voir le message
    Il faut donc que je puisse définir facilement à quel endroit ce trouve ces sauts de lignes afin de traiter par la suite chaque bloc séparément...
    D'après ce que je comprends de ce type de contrôle graphique:

    - quand tu demandes l'affichage d'une chaine qui dépasse la ligne d'affichage du contrôle, c'est lui qui décide à quel endroit de la chaine il génère le passage à la ligne suivante.

    - quand tu lis une telle chaine à partir du contrôle, celui-ci te redonne une chaine complète sans la fin de ligne.

    Donc, tu n'as jamais accès à un caractère de fin de ligne d'affichage du contrôle.

    Si tu veux calculer toi même la fin de ligne d'affichage du contrôle, il faut utiliser certaines fonctions de la bibliothèque graphique qui permettent de calculer le nb de pixels d'une chaine en fonction de sa police, et la longueur d'affichage en pixels. Et tenir compte en plus des possibilités de coupure de phrases (espace par exemple). Bref, faire ce que le contrôle fait nécessairement en interne.

    C'est ça que je ne sais pas faire en wx, mais je l'ai déjà fait dans le passé avec une autre langage, et je sais donc que c'est possible. Regarde bien la doc de wx + recherche google.

    Et compte tenu de la complexité de ton pb, peut-être devrais-tu ouvrir un nouveau fil pour susciter de nouvelles réponses.

    Tyrtamos

  10. #10
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    - quand tu demandes l'affichage d'une chaine qui dépasse la ligne d'affichage du contrôle, c'est lui qui décide à quel endroit de la chaine il génère le passage à la ligne suivante.

    - quand tu lis une telle chaine à partir du contrôle, celui-ci te redonne une chaine complète sans la fin de ligne.

    Donc, tu n'as jamais accès à un caractère de fin de ligne d'affichage du contrôle.
    On est bien d'accord... sauf si c'est moi qui provoque ce saut de ligne grâce à la touche entrée, car le wx.TextCtrl en version multiligne supporte cette touhce. Et c'est bien ce saut de ligne que je souhaite reproduire.

    Le saut de ligne automatique lié en fait à la largeur de ma fenêtre ne m'importe pas.
    Pour faire simple je veux juste faire de cette fenêtre une fenêtre de traitement de texte simpliste.

    Je vais regarder de plus prêt la réponse de eyquem et si je ne parviens pas à trouver une solution qui me convient j'ouvrirai effectivement un autre fil.

    En tout cas merci à vous deux

    [EDIT]
    Je viens juste de faire un essai avec la fonction repr(). J'avais déjà trouvé cette fonction dans un exemple et je pensai que c'était une fonction propre à cet exemple...
    Erreur c'est une fonction de python qui me permettra très facilement de faire ce que je veux.

    Merci bien

    Post définitivement résolu
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

  11. #11
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    J'ai exactement le même besoin que toi. J'utilise wxPython et Reportlab pour me faire un pdf.

    Ma version de wxPython est la version unicode (donc tout ce que je récupère des TextCtrl est de l'unicode)

    J'ai également des TextCtrl multiligne. Voici ce que je fais. Je n'ai jamais eu (pour le moment) de problème avec mes caractères (en même temps, je ne suis jamais allé trop loin au niveau du test des caractères unicode).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    c= reportlab.pdfgen.canvas.Canvas("toto.pdf")
    mm = reportlab.lib.units.cm / 10.
    mystyle = reportlab.lib.styles.getSampleStyleSheet()['Normal']
    mystyle.fontSize = 10
    mystyle.alignment = reportlab.lib.enums.TA_JUSTIFY
    frame = reportlab.platypus.Frame(0, 151*mm, 95*mm, 124*mm, leftPadding=1, bottomPadding=1, rightPadding=1, topPadding=1, id=None, showBoundary=0)            
    p = []
    for i in MyTextCtrl.GetValue().split("\n"):
        p.append(reportlab.platypus.Paragraph(i, mystyle))
    frame.addFromList(p, c)

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Ayant lu la dernière réponse de tyrtamos, je pense être largement à coté du vrai problème.

    Je mets quand même ce qui suit, au cas où.









    Pour connaître les positions des newlines dans une chaîne:



    sans re

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    x = ch.find('\n')
    li = []
    while x+1:
        li.append(x)
        x = ch.find('\n',x+1)
    Mais c'est peu sûr parce qu'il peut y avoir \r aussi dans la chaîne.

    Mieux vaut alors utiliser re

    soit pour trouver les positions des newlines:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ch = 'pomme\nnoisette\navocat\r\ngrenade\nkaki\nfruit de la passion\npoire'
     
    import re
     
    print list(u.start() for u in re.finditer('\r?\n',ch))




    soit pour obtenir directement les positions du début et de la fin de chaque ligne (avant newline) pour l'ensemble des lignes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print list(u.span() for u in re.finditer('^.+?$',ch,re.MULTILINE))

  13. #13
    Rédacteur/Modérateur

    Avatar de Jiyuu
    Homme Profil pro
    Développeur amateur
    Inscrit en
    Janvier 2007
    Messages
    2 456
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur amateur
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 456
    Billets dans le blog
    15
    Par défaut
    Re,

    Le for...in de GuiGui est exactement ce que je cherchais. Ajouté à ma petite modif de Paragraph.py il me permet de faire exactement ce que je souhaite.

    Ta solution eyquem avec repr() est super intéressante car en fait cette focntion (que je ne connaissais pas) permet de "représenter" tous les caractères et de ce fait même les "é", "è"... apparaissent sous leur forme unicode (enfin je crois que c'est celle-ci car là je commence à me pommer un dans les coding.)
    Ceci apporte pas mal d'atouts mais aussi un inconvénient majeur... il faut re-encoder derrière.

    La méthode de GuiGui évite ceci.

    Pour finir et pour tous ceux qu'ils veulent créer des pdf facilement avec Python, voici ce que j'utilise... (avec les petites améliorations que j'ai pu faire grâce à ce topic)


    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    import sys
    import reportlab.platypus as rpb
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.rl_config import defaultPageSize
    PAGE_HEIGHT=defaultPageSize[0]
    from reportlab.lib.units import cm
    from reportlab.lib import colors, fonts
    import os
    try: import psyco; psyco.full() 
    except: pass
     
    time = wx.DateTime()
    now = time.Now()
    jour = now.GetDay()
    mois = now.GetMonth()
    an = now.GetYear()
    now = '%s / %s / %s' % (jour, mois+1, an)
     
    p = rpb.Paragraph
     
    PROJECT_PATH = os.getcwd()
     
    #p > imprime du bout à bout avec retour à la ligne automatique.
    #pre > imprime exactement comme c'est écrit dans le script
     
    Title = ""
    Firm = 'xxx'
    Author = "Ch.E"
    URL = ""
    email = ""
     
    pageinfo = "%s / %s / %s / %s" % (Firm, URL, Author, email)
    Elements = []
     
    styles = getSampleStyleSheet()
    PS = ParagraphStyle
     
    HeaderStyle = styles["Heading1"] # XXXX
    ParaStyle = styles["Normal"]
    PreStyle = styles["Code"]
     
    def font(name = 'courier', size = 13, indent = 0, align = 0):
    	a = PS(fontName=name, fontSize=size, name='TOCHeading1',leftIndent=indent, alignment = align)
    	return a
     
     
    def saut(y):
    	return Elements.append(rpb.Spacer(1, y * cm))
     
    def posx(a):
    	x = a * cm
    	return x
     
    def posy(b):
    	y = (29 - b) * cm
    	return y
     
    def myFirstPage(canvas, doc):
    	canvas.beginText(30,10)
    	canvas.saveState()
    	canvas.setFont('Times-Bold',16)
    	canvas.drawImage(PROJECT_PATH+"\\images\\img\\atell.jpeg", posx(0.5), posy(2.3), 400, 80)
    	canvas.drawString(posx(6.5), posy(2.8), Title)
    	canvas.setFont('Courier',11)
    	canvas.drawString(posx(12), posy(3.5), u"%s" % ste)
    	canvas.drawString(posx(12), posy(4), u"A l'attention de %s %s" % (civ, nom))
    	canvas.drawString(posx(12), posy(4.5), u"%s" % adresse)
    	canvas.drawString(posx(12), posy(5), u"%s" % ' ' )
    	canvas.drawString(posx(12), posy(5.5), u"%s %s" % (cp,ville))
    	canvas.setFont('Times-Roman',9)
    	canvas.drawString(0.5*cm, 40, "Page %d / %s" % (doc.page, pageinfo))
    	canvas.setFont('Times-Bold',9)
    	canvas.restoreState()
     
     
    def myLaterPages(canvas, doc):
    	canvas.saveState()
    	canvas.setFont('Times-Bold',16)
    	canvas.drawImage(PROJECT_PATH+"\\images\\img\\atell.jpeg", posx(0.5), posy(2.3), 400, 80)
    	canvas.drawString(posx(6.5), posy(2.8), Title)
    	canvas.setFont('Courier-Bold',12)
    	canvas.drawString(posx(1), posy(3.5), u"Référence Chantier :")
    	canvas.drawString(posx(15), posy(3.5), "Date : %s"%now)
    	canvas.setFont('Times-Roman',9)
    	canvas.drawString(0.5*cm, 40, "Page %d / %s" % (doc.page, pageinfo))
    	canvas.setFont('Times-Bold',9)
    	canvas.restoreState()
     
    def header(txt, style=HeaderStyle, klass=rpb.Paragraph, sep=0.1, x = 1, y = 1):
    	s = rpb.Spacer(x, y)
    	Elements.append(s)
    	para = klass(txt, style)
    	Elements.append(para)
     
    def pre(txt):
    	s = rpb.Spacer(200, 5)
    	Elements.append(s)
    	p = rpb.Preformatted(txt, ParaStyle)
    	Elements.append(p)
     
     
    def font_tab(txt, taille = 12):
    	t = p(u'%s'%txt, font(size = taille))
    	return t
     
    def tableau(colone_a, colone_b):
    	if len(colone_b) == 0:
    		for i in range(len(colone_a)):
    			colone_b.append('')
    	list_tab = []
    	for i in range(len(colone_a)):
    		a = [colone_a[i], colone_b[i]]
    		list_tab.append(a)
     
    	t1=rpb.Table(list_tab)
    	t1.setStyle(rpb.TableStyle([('FONTSIZE', (0,0),(-1,-1),11),
    								('FONTNAME', (0,0), (-1,-1), 'Courier'),
    								('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
    								('BOX', (0,0), (-1,-1), 0.5, colors.black)]))	
    	return t1
     
    def first_page():
    	saut(5)
     
     
    def new_page():
    	Elements.append(rpb.PageBreak())
    	saut(5)
     
    def img(path, x = 1, y = 1):
    	new_img = rpb.Image(path, x*cm, y*cm)
    	Elements.append(new_img)
     
    def para(txt, style):
    	for i in txt.split("\n"):
    		Elements.append(p(i, style))
    		saut(0.1)
     
    def go(path, titre = 'Sans nom', margin = (0.5,0.5,0.5,0.5), projet = []):
    	Elements.insert(0,rpb.Spacer(0,0))
    	doc = rpb.SimpleDocTemplate(path, title = titre, leftMargin = margin[0]*cm, rightMargin = margin[1]*cm, 
    								topMargin = margin[2]*cm, bottomMargin = margin[3]*cm)
    	doc.build(Elements,onFirstPage=myFirstPage, onLaterPages=myLaterPages)
    J'ai fait un pur copier-coller de mon code, il est donc possible que certaines choses ne soient pas utile ou qu'il en manque des bouts... mais dans les grandes lignes ça permet de faire pas mal de chose assez facilement.
    Initiation à Qt Quick et QML : Partie 1 - Partie 2
    En cas de besoin, pensez à la
    Mon site et mes tutoriaux sur Developpez.com
    Pas de question technique par MP... Les forums sont là pour ça

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

Discussions similaires

  1. Problème de session (encore)
    Par akapando dans le forum Langage
    Réponses: 2
    Dernier message: 23/05/2006, 16h54
  2. Problème de codage de caractères depuis l'import
    Par compu dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 22/03/2006, 08h37
  3. Réponses: 3
    Dernier message: 22/03/2005, 09h13
  4. Réponses: 9
    Dernier message: 04/03/2005, 13h58
  5. [Accents - XML] Problème de codage non supporté !!
    Par Smortex dans le forum Composants VCL
    Réponses: 6
    Dernier message: 24/11/2002, 11h00

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