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 :

Header et footer dans un QPrintPreviewDialog


Sujet :

PyQt Python

  1. #1
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut Header et footer dans un QPrintPreviewDialog
    Bonjour à tous,

    Je poursuis mes recherches dans PySide ...
    Je cherche à faire apparaitre un texte (QTextDocument) avec un header et un footer (tous les 2 QTextDocument) dans un QPrintPreviewDialog.

    J'ai étudié avec attention le post de référence :http://www.developpez.net/forums/d11...tement-textes/. La solution proposée s'articule autour de l'utilisation de QPainter sur un printer avec des modifications et des translations de rectangles (QtCore.QRectF) appliquées au QTextDocument à imprimer.
    La solution est super et le principe fonctionne bien si l'on veut imprimer directement le document ou l'enregistrer en pdf. Je voudrais pouvoir prévisualiser le document avec son en-tête et son pied de page avant de l'imprimer ou de l'enregistrer en pdf.
    J'ai essayé plusieurs pistes avec plus ou moins de succès et j'aimerais bien avoir vos avis.

    1 - Utiliser les mêmes principes (QPainter et QRectF) mais sur autre chose qu'un printer (??). Récupérer le tout dans un nouveau QTextDocument et l'afficher dans le QPrintPreviewDialog.
    2 - Utiliser les commandes (déplacement, insertion) de QTextCursor et de QTextDocument (création et dimension)

    1 - J'ai essayé d'utiliser painter sur un QTextEdit. Après quelques échecs, j'ai réussi à "peindre" sur le viewport() mais je n'ai pas réussi à récupérer le contenu dans un QTextDocument ...
    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
    class TextEdit(QtGui.QTextEdit):
        def __init__(self, header, document, footer, parent = None):
            super(TextEdit, self).__init__(parent)
            self.header = header
            self.document = document
            self.footer = footer
     
        def paintEvent(self, event):
            print "paintEvent"
            painter = QtGui.QPainter(self.viewport())
            self.header.drawContents(painter)
            painter.translate(0, self.header.size().toSize().height())
            self.document.drawContents(painter)
            painter.translate(0, self.document.size().toSize().height())
            self.footer.drawContents(painter)
    2 - J'ai réussi à faire "quelque chose" mais qui me parait assez compliqué et que je n'arrive pas à maitriser complètement :
    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
     
    #!/usr/bin/python
    # -*- coding: ISO-8859-1 -*-
     
    import sys
    from PySide import *
     
    class Report(QtGui.QFrame):
        '''  '''
        def __init__(self):
            super(Report, self).__init__()
            # Définition des marges
            margeGauche = 30
            margeHaut = 100
            margeDroite = 10
            margeBas = 40
            margeHeader = 20
            margeFooter = 40
            printer = QtGui.QPrinter()
            printer.setPageMargins(margeGauche, margeHaut, margeDroite, margeBas, QtGui.QPrinter.DevicePixel)
     
            innerRect = printer.pageRect()
            sizeF = QtCore.QSizeF(innerRect.size().width(), innerRect.size().height())
            # Définition des header, footer et document à imprimer
            doc = QtGui.QTextDocument()
            self.doc = doc
            cursor = QtGui.QTextCursor(doc)
            format1 = QtGui.QTextCharFormat()
            format1.setFontPointSize(16)
            format2 = QtGui.QTextCharFormat()
            format2.setFontPointSize(8)
            cursor.insertText(" 999 Titre de l'état -- Suite __ suite vvgg == abcde 111 " * 10, format1)
            cursor.insertText("Titre de l'état -- Suite __ suite vvgg == abcde " * 400, format2)
     
            header = QtGui.QTextDocument()
            header.setPageSize(sizeF)
            self.header = header
            cursor_header = QtGui.QTextCursor(header)
            format1 = QtGui.QTextCharFormat()
            format1.setFontPointSize(16)
            cursor_header.insertText("------EnTete --- EnTete --------" * 20)
            cursor_header.select(QtGui.QTextCursor.Document)
            fragment_header = cursor_header.selection()
     
            footer = QtGui.QTextDocument()
            footer.setPageSize(sizeF)
            self.footer = footer
            cursor_footer = QtGui.QTextCursor(footer)
            cursor_footer.insertText("------Pied de page --- Pied de page --------" * 10)
            cursor_footer.select(QtGui.QTextCursor.Document)
            fragment_footer = cursor_footer.selection()
     
            blockFormatSaut = QtGui.QTextBlockFormat()
            blockFormatSaut.setPageBreakPolicy(QtGui.QTextFormat.PageBreak_AlwaysBefore)
            blockFormatHeader = QtGui.QTextBlockFormat()
            blockFormatHeader.setPageBreakPolicy(QtGui.QTextFormat.PageBreak_Auto)
            blockFormatHeader.setTopMargin(margeHeader)
            blockFormatFooter = QtGui.QTextBlockFormat()
            blockFormatFooter.setPageBreakPolicy(QtGui.QTextFormat.PageBreak_Auto)
            blockFormatFooter.setTopMargin(margeFooter)
     
            doc.setPageSize(sizeF)
     
            contentHeight = (innerRect.size().height() - 
            header.size().toSize().height() - margeHeader - 
            footer.size().toSize().height() - margeFooter)
            contentSize = QtCore.QSize(innerRect.size().width(), contentHeight)
            contentRect = QtCore.QRect(QtCore.QPoint(margeGauche, margeHaut), contentSize)
            totalPages = doc.size().toSize().height() / contentHeight + 1
     
            docF = QtGui.QTextDocument()
            docF.setPageSize(contentSize)
            cursorF = QtGui.QTextCursor(docF)
            cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.MoveAnchor)
     
            docP = QtGui.QTextDocument()
            docP.setPageSize(contentSize)
            docF.setDocumentMargin(40)
            cursorP = QtGui.QTextCursor(docP)
            nb = 1
            max = (contentHeight - margeHaut - margeBas - margeFooter 
            - margeHeader - header.size().toSize().height() - footer.size().toSize().height())
     
            while docP.size().height() < max :
                cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.MoveAnchor)
                cursor.movePosition(cursor.Down, QtGui.QTextCursor.KeepAnchor, nb)
                docP.setHtml(cursor.selection().toHtml())
                nb += 1
     
            cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.MoveAnchor)
            cursor.movePosition(cursor.Down, QtGui.QTextCursor.KeepAnchor, nb - 2)
            fragment = cursor.selection()
            cursorF.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.MoveAnchor)
            cursorF.insertFragment(fragment_header)
            cursorF.insertBlock(blockFormatHeader)
            cursorF.insertFragment(fragment)
            cursorF.insertBlock(blockFormatFooter)
            cursorF.insertFragment(fragment_footer)
     
            dialog = QtGui.QPrintPreviewDialog()
            dialog.paintRequested.connect(docF.print_)
            dialog.exec_() 
     
    def main():
        app = QtGui.QApplication(sys.argv)
        frame = Report()
        frame.show()
        sys.exit(app.exec_())
     
    if __name__ == '__main__':
        main()
    La "chose" n'est pas terminée (Je n'ai formaté qu'une page)...
    Qu'en pensez-vous ?
    Cordialement.

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

    Il est normal de vouloir visualiser une page avant de l'imprimer. Pour ma part, voilà comment je fais:

    Après création de la page (ou des pages), je l'enregistre dans un fichier temporaire, puis j'en demande l'affichage par le "pdfreader" de l'OS (adobe ou autre). Et c'est en fait à partir de ce pdfreader que j'imprime sur papier.

    Voilà comment j'appelle le programme par défaut (ici le pdfreader):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #############################################################################
    def affiche_url(chu):
        """affiche chu (chaine unicode) avec le programme par défaut de l'OS
           chu peut être une adresse web ou un fichier sur disque
        """
        if os.path.exists(chu):
            # ajoute "file:///" si nécessaire
            url = QtCore.QUrl.fromLocalFile(os.path.abspath(chu)) 
        else:
            # ajoute "http://" si nécessaire
            url = QtCore.QUrl.fromUserInput(chu) 
        # appelle le programme par défaut pour affichage de l'url
        QtGui.QDesktopServices.openUrl(url)
    Je l'utilise sur Windows, mais il devrait être multiplateforme (à confirmer).

    Il reste que je suivrai avec intérêt la suite de ce fil: il n'y a pas de monopole pour les bonnes idées...
    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 actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Octobre 2008
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 330
    Points : 207
    Points
    207
    Par défaut
    Bonsoir Tyrtamos,

    Je te remercie pour tes conseils. En effet, en attendant de trouver mieux je pense que c'est la solution la plus simple à mettre en œuvre.
    Il y a néanmoins quelques points qui me gênent dans cette approche et que je voudrais bien régler ( ... qui me restent à régler ... ):

    1- Quand on restreint drawContents avec QRectF on peut couper la dernière ligne, voire une image ( je n'ai pas bien compris comment vous traitiez ce problème dans le fil http://www.developpez.net/forums/d11...tement-textes/ ...)

    2 - On doit définir l'orientation de l'impression a priori (Landscape ou Portrait) dans le code, lancer l'impression dans le fichier temporaire puis visualiser dans le reader. Si on veut pouvoir modifier l'orientation de façon interactive, il faudrait, je pense, créer un petit interface. C'est dommage car dans QPrintPreviewDialog c'est prévu (en passant je ne sais pas comment on peut intercepter et surcharger ses méthodes ...). Néanmoins, ce n'est pas un point bloquant et c'est peut être une bonne idée qui permettrait de proposer également d'autres options (comme la 'conservation' du fichier temporaire comme un 'vrai' fichier de sortie ...)

    3 - J'aurais bien voulu trouver une solution 100 % Python- PySide/Qt sans passer par le reader pdf de l'OS ...

    Je continuer à bécher ce terrain et je vous tiens au courant. Je reste à votre écoute également.
    Cordialement,

Discussions similaires

  1. VBA Zone de texte dans header et footer
    Par wiidle dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 10/08/2011, 09h39
  2. [WS 2003] Active directory et header/footer dans office
    Par mavina dans le forum Windows Serveur
    Réponses: 1
    Dernier message: 25/03/2010, 16h35
  3. Réponses: 8
    Dernier message: 15/11/2008, 10h09
  4. Réponses: 1
    Dernier message: 01/10/2008, 11h33
  5. mise en page (Header and Footer) en XML-XSL.
    Par christine dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 01/03/2004, 16h31

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