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 :

[PyQt5] Problème affichage et attribut de classe


Sujet :

PyQt Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Points : 17
    Points
    17
    Par défaut [PyQt5] Problème affichage et attribut de classe
    Bonjour,

    Je suis en train de coder une application avec laquelle je crée (entre autre) mes séquences de cours. A la fin de chaque traitement je voudrais afficher la fiche de cours produite sous forme de fichier PDF.

    Tout fonctionne bien sauf l'affichage dans l'onglet Visualisation (classe Visionnage). En fait je voudrais qu'a la fin de chaque traitement la fiche correspondante (les fichiers pdf produits, avec un nombre de pages qui peuvent être 1, 2, 3, ... selon les cas) s'affiche dans l'onglet Visualisation et contenu dans un QGraphicsView. A la fin de chaque traitement les fichiers pdf des séquences sont convertis en images png (dans le répertoire temporaire), je voudrais que par l'intermédiaire de la classe Visionnage (voir mon code plus bas) les images produites s'affichent dans un QGraphicsView piloté par un bouton correspondant à chaque page (chaque image). Pour l'instant ça ne fonctionne pas quand je passe par l'appel de la classe Visionnage avec l'attribut liste_images. Pouvez-vous m'aider ?

    J'ai mis une copie d'écran de ce que je voudrais obtenir (l'image jointe avec les boutons en bas (Vue page 1, ...)).

    Pour précision, je ne suis pas du tout un expert.

    Voici une partie de mon script main :

    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
    ...
     
    class APSC_GUI(QMainWindow):
        # Classe GUI principale
        def __init__(self):
            super(APSC_GUI, self).__init__()
     
            # Version de PyQt5 et de Qt
            APSC_Print("PyQt {0} et Qt {1}".format(PYQT_VERSION_STR, QT_VERSION_STR))
     
            # Appel de la classe de la séquence prof
            self.seq_p = APSC_Sequence_Prof()
     
            # Titre
            self.setWindowTitle('ArtsPlastocSequenceConceptor')
            # Logo/icône pour la fenêtre
            self.setWindowIcon(QIcon('logo_png_apsc'+os.sep+'logo_apsc_256x256.png'))
     
            self.setGeometry(20, 40, 900, 760)
            # La taille minimum est fixée à 900 x 760
            self.setMinimumSize(900, 760)
     
            # Appel de la classe de mise en page de la séquence élève
            self.mep_seq_elev = MiseEnPageSequenceEleve(parent=None)
     
            # Appel de la fonction affichant le menu
            self.menus()
     
            # ============================================= #
            # Boîte d'onglets
            self.tab_widget = QTabWidget()
     
            # Appel des classes contenant le groupement de widgets
            self.win_widget_1 = APSC_Sequence_Prof(self)
            self.win_widget_2 = MiseEnPageSequenceEleve(self)
            self.win_widget_3 = FeuilleEvaluation(self)
            self.win_widget_4 = Visionnage(self)
            self.win_widget_5 = Info(self)
     
            # Le widget
            widget = QWidget()
     
            layout = QVBoxLayout(widget)
     
            # On liste le contenu du répertoire temporaire ...
            liste_contenu_tmp = os.listdir(tempfile.gettempdir())
     
            # ------------------------------------------------------
            # Au tout 1er démarrage d'APSC, le fichier temporaire :
            # data_affichage_onglets_apsc ... n'existe pas encore.
            # Tant que l'utilisateur n'aura pas sélectionné le type
            # d'Apparence des onglets de sélection des rubriques, 
            # cela s'affichera en 'mode' texte
            # ------------------------------------------------------
            # Boucle de vérification ...
            for contenu in liste_contenu_tmp :
                # 
                if 'data_affichage_onglets_apsc' not in contenu :
                    # On rajoute chaque onglet ... en 'mode' texte
                    self.tab_widget.addTab(self.win_widget_1, "Séquence du professeur")
                    self.tab_widget.addTab(self.win_widget_2, "Fiche élève")
                    self.tab_widget.addTab(self.win_widget_3, "Feuille d'évaluation")
                    self.tab_widget.addTab(self.win_widget_4, "Visualisation")
                    self.tab_widget.addTab(self.win_widget_5, "Aide et informations")
     
            # ---------------------------------------------------------
            # Si l'apparence des onglets a déjà été modifié, c'est à
            # dire que l'utilisateur a déjà sélectionné le type
            # d'Apparence des onglets de sélection des rubriques, cela
            # s'affichera dans le 'mode' choisi par l'utilisateur
            # ---------------------------------------------------------
            # Boucle de vérification ...
            for contenu in liste_contenu_tmp :
                # Si le fichier tempo concerné est bien 
                # dans le répertoire temporaire ...
                if 'data_affichage_onglets_apsc' in contenu :
                    # ------------------------------------------------------- #
                    # Utilisation de la classe Tempo_lecture pour la lecture
                    # des données dans le répertoire (dit) temporaire
                    # ------------------------------------------------------- #
                    rep_tempo_lecture = Tempo_lecture(tempfile.gettempdir(), os.getcwd(), 'data_affichage_onglets_apsc_', 'data_affichage_onglets_apsc')
                    # ... avec appel de la méthode affichage
                    rep_tempo_aff = rep_tempo_lecture.affichage()[0]
                    # Si sélection en 'mode' Texte uniquement ...
                    if rep_tempo_aff == 'Texte uniquement' :
                        self.tab_widget.addTab(self.win_widget_1, "Séquence du professeur")
                        self.tab_widget.addTab(self.win_widget_2, "Fiche élève")
                        self.tab_widget.addTab(self.win_widget_3, "Feuille d'évaluation")
                        self.tab_widget.addTab(self.win_widget_4, "Visualisation")
                        self.tab_widget.addTab(self.win_widget_5, "Aide et informations")
                    # Si sélection en 'mode' Texte et icônes ...
                    if rep_tempo_aff == 'Texte et icônes' :
                        self.tab_widget.addTab(self.win_widget_1, QIcon(os.path.join('logo_png_apsc', 'icone_tete_de_prof_apsc_256x256.png')), "Séquence du professeur")
                        self.tab_widget.addTab(self.win_widget_2, QIcon(os.path.join('logo_png_apsc', 'icone_tete_d_eleve_apsc_256x256.png')), "Fiche élève")
                        self.tab_widget.addTab(self.win_widget_3, QIcon(os.path.join('logo_png_apsc', 'icone_evaluation_apsc_256x256.png')), "Feuille d'évaluation")
                        self.tab_widget.addTab(self.win_widget_4, QIcon(os.path.join('logo_png_apsc', 'icone_visualisation_apsc_256x256.png')), "Visualisation")
                        self.tab_widget.addTab(self.win_widget_5, QIcon(os.path.join('logo_png_apsc', 'icone_aide_version_apsc_256x256.png')), "Aide et informations")
                        # Taille de l'icône dans le QTabWidget
                        self.tab_widget.setIconSize(QSize(24, 24))
                    # Si sélection en 'mode' Icônes uniquement ...    
                    if rep_tempo_aff == 'Icônes uniquement' :
                        self.tab_widget.addTab(self.win_widget_1, QIcon(os.path.join('logo_png_apsc', 'icone_tete_de_prof_apsc_256x256.png')), None)
                        self.tab_widget.addTab(self.win_widget_2, QIcon(os.path.join('logo_png_apsc', 'icone_tete_d_eleve_apsc_256x256.png')), None)
                        self.tab_widget.addTab(self.win_widget_3, QIcon(os.path.join('logo_png_apsc', 'icone_evaluation_apsc_256x256.png')), None)
                        self.tab_widget.addTab(self.win_widget_4, QIcon(os.path.join('logo_png_apsc', 'icone_visualisation_apsc_256x256.png')), None)
                        self.tab_widget.addTab(self.win_widget_5, QIcon(os.path.join('logo_png_apsc', 'icone_aide_version_apsc_256x256.png')), None)
                        # Taille de l'icône dans le QTabWidget
                        self.tab_widget.setIconSize(QSize(32, 32))
     
            # Onglets positionnés au centre
            self.tab_widget.setStyleSheet("""QTabWidget::tab-bar {alignment: center;}""")
     
            layout.addWidget(self.tab_widget)
     
            self.setCentralWidget(widget)
     
    ...
    Une partie du code la la classe APSC_Sequence_Prof :

    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
    ...
     
            # ==========================================================
            # Gestion de la visualisation (dans l'onglet Visualisation)
            # ==========================================================
     
            # Si des images PNG d'une fiche prof, ou d'une fiche
            # élève, ou d'une fiche d'évaluation existe déjà, 
            # elles sont éliminées avant d'en recréer d'autres
     
            # On liste le contenu du répertoire temporaire ...
            liste_contenu_tmp = os.listdir(tempfile.gettempdir())
            # ... ou du répertoire courant ...
            liste_contenu_rep_courant = os.listdir(os.getcwd())
     
            # ------------------------------------------------------------
            # Exception pour contrôler le répertoire temporaire utilisé
            # ------------------------------------------------------------
            try :
                for contenu in liste_contenu_tmp :
                    # Si le fichier tempo concerné est bien dedans ...
                    if 'pdf_png_apsc' in contenu :
                        APSC_Print("Le fichier temporaire contient déjà des fiches (prof, élève ou évaluation) ; le fichier {} est éliminé".format(contenu))
                        APSC_Print(" ")
                        os.remove(tempfile.gettempdir()+os.sep+contenu)
            except :
                for contenu in liste_contenu_rep_courant :
                    if 'pdf_png_apsc' in contenu :
                        APSC_Print("Le fichier temporaire contient déjà des fiches (prof, élève ou évaluation) ; le fichier {} est éliminé".format(contenu))
                        APSC_Print(" ")
                        os.remove(os.getcwd()+os.sep+contenu)        
     
            # Chemin et nom de fichier du fichier PDF à traiter
            pdf_traitement = optio_2[0]
            # Chemin (dans le répertoire temporaire) et nom des images (PNG)
            img_traitement = tempfile.gettempdir()+os.sep+'pdf_png_apsc'
            # Sous windows ... 
            if os.name == 'nt' :
                import subprocess
                # ... on utilise directement l'exécutable pdftoppm.exe
                # (se trouvant ds le répertoire racine (courant))
                pdftoppm_executable = "pdftoppm.exe"
                # La commande ...
                commande = "{} -r 96 -png -aa yes {} {}".format(pdftoppm_executable, pdf_traitement, img_traitement)
                #
                subprocess.call(commande, shell = True)
            # Sous GNU/Linux ...    
            else : 
                # On utilise le module pdf2image ... installé par 
                # la commande : pip3 install pdf2image
                from pdf2image import convert_from_path
                pages = convert_from_path(pdf_traitement, 96)
                for n, page in enumerate(pages) :
                    page.save(img_traitement+'-'+str(n+1)+'.png', 'PNG')
            # ==========================================================
     
            liste_contenu_tmp_2 = os.listdir(tempfile.gettempdir()) ###############
            print(liste_contenu_tmp_2) ##########
            import glob ##########
            print("glob", glob.glob(tempfile.gettempdir()+os.sep+'pdf_png_apsc*.png')) ###########
            liste_images = glob.glob(tempfile.gettempdir()+os.sep+'pdf_png_apsc*.png') #########
     
            # Visionnage des séquences prof et élève
            from affichage_apsc.visionnage_gui import Visionnage ##############
            visio = Visionnage(liste_images, parent=None) ################
     
            # Temps de traitement ... (pour info)
            elapsed_seconds = (datetime.datetime.now() - start).total_seconds()
            secondes = float(elapsed_seconds % 60)
            secondes_ecoulees = "{0:.2f}".format(round(secondes, 2))
            APSC_Print("Secondes écoulées : {}".format(secondes_ecoulees))
     
    ...
    Voici ma classe Visionnage (en chantier), ... le QGraphicsView n'affiche rien àa la fin du traitement :

    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
    ...
     
    # Je me suis inspiré de ce post sur Stackoverflow : 
    # https://stackoverflow.com/questions/49670506/reading-frames-from-a-folder-and-display-in-qgraphicsview-in-pyqt4
    # ... en l'adaptant complètement à mon besoin ...
     
    # Gérer les print ...
    #from affichage_apsc.apsc_print import APSC_Print
     
    # Merci à eyllanesc pour son aide est pour cette classe ... import
    # --> pour les icônes à gauche dans le bouton
    # --> https://stackoverflow.com/questions/53415379/align-icon-on-the-right-and-center-the-text-in-a-qpushbutton
    from affichage_apsc.push_button_icone_gauche import PushButtonIconeGauche
     
    import os, tempfile
     
    # Imports PyQt5 -----------------------------------------------------------------------
    from PyQt5.QtWidgets import QWidget, QGroupBox, QPushButton, QGridLayout, \
                                QGraphicsScene, QGraphicsView, QGraphicsPixmapItem, \
                                QApplication
    from PyQt5.QtCore import QSize, Qt, QTimer
    from PyQt5.QtGui import QPixmap, QIcon
    # --------------------------------------------------------------------------------------
     
     
    class Visionnage(QWidget):
        ''' Classe pour visionner le résultat (en images PNG de chaque 
        page en PDF) des fiches prof, élève ou évaluation, selon les cas '''
     
        def __init__(self, liste_images, parent=None):
            #super(Visionnage, self).__init__(parent)
            super().__init__()
     
            self.liste_images = liste_images
     
            #"""
            ###############################
            #if str(type(self.liste_images)) == "<class 'list'>" : ###########
            try :
                print('OKKKKKKK') ############
     
                print("Images Temp", self.liste_images) #######
                print(type(self.liste_images)) ######
     
                # Utilisation QGraphicsScene et QGraphicsView
                self.scene  = QGraphicsScene()
                self.graphique_vue = QGraphicsView(self.scene)
     
                # Dictionnaire des botons des pages de visionnement           
                self.dico_bouton_visio = {}
     
                # Icône pour le bouton ...
                icone = QIcon(os.path.join('logo_png_apsc', 'icone_visualisation_apsc_256x256.png'))            
     
                # =====================================================
                groupe_1 = QGroupBox()
                groupe_2 = QGroupBox()
     
                grid_1 = QGridLayout()
                grid_1.setSpacing(10)
     
                grid_2 = QGridLayout()
                grid_2.setSpacing(10)
     
                # Ajout du QGraphicsView ds la grille 1
                grid_1.addWidget(self.graphique_vue, 0, 0)
     
                print("len(self.liste_images)", len(self.liste_images))
     
                # Boucle pour lister le nombre d'images et
                # attribuer les boutons en conséquence
                for n, i in enumerate(self.liste_images) :
                    #for n in range(6) : # A GARDER !
     
                    print("Image tempo {}".format(n), i)
     
                    # Bouton pour ajouter une ligne pour les questions d'enseignement
                    self.dico_bouton_visio[n] = PushButtonIconeGauche("Vue page {}".format(n+1), icon = icone, iconSize = QSize(16, 16))
     
                    # Ajout du ou des bouton(s) dans la grille 2
                    grid_2.addWidget(self.dico_bouton_visio[n], 0, n) # A GARDER !
     
                    #QApplication.processEvents() #########
     
                    if n == 0 : self.dico_bouton_visio[0].clicked.connect(lambda : self.afficher(0))
                    elif n == 1 : self.dico_bouton_visio[1].clicked.connect(lambda : self.afficher(1))
                    elif n == 2 : self.dico_bouton_visio[2].clicked.connect(lambda : self.afficher(2))
                    elif n == 3 : self.dico_bouton_visio[3].clicked.connect(lambda : self.afficher(3))
                    elif n == 4 : self.dico_bouton_visio[4].clicked.connect(lambda : self.afficher(4))
                    elif n == 5 : self.dico_bouton_visio[5].clicked.connect(lambda : self.afficher(5))                  
     
                #
                grid_1.setAlignment(Qt.AlignVCenter)
                #
                groupe_1.setLayout(grid_1)
                groupe_2.setLayout(grid_2)
     
                layout = QGridLayout()
                layout.addWidget(groupe_1, 0, 0)
                layout.addWidget(groupe_2, 1, 0)
                #
                self.setLayout(layout)
     
            #elif str(type(self.liste_images)) == "<class '__main__.APSC_GUI'>" : ###########
            except :
                print('Pas Oké !!!') #############
                pass
     
     
        def afficher(self, n) :
            ''' Fonction pour afficher une image PNG de la fiche 
            prof, de la fiche élève (ou de la fiche d'évaluation), 
            en cours '''
     
            #try :
            self.scene.clear() ##########
            self.graphique_vue.items().clear() ##########
     
            images = self.liste_images[n]
            pixmap = QPixmap(images)
            item   = QGraphicsPixmapItem(pixmap)
            self.scene.addItem(item)
            self.graphique_vue.setScene(self.scene)
            #
            self.graphique_vue.show()
            #except : return
    J'espère que vous pourrez me donner un coup de main ...

    J'espère aussi avoir été suffisamment clair dans mes explications.

    Je vous remercie d'avance.

    a+
    Images attachées Images attachées    

  2. #2
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Je m'aperçois (en me relisant), que ma demande n'est pas claire du tout !

    J'ai un peu modifié ... en me posant des questions sur le contexte d'exécution ...

    La classe Visionnage est d'abord lancée dans le main. Elle est de nouveau relancée après le traitement de la séquence du professeur (je suis revenu à ce que j'avais essayé au départ) :

    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
     
    ...
            # ==========================================================
            # Gestion de la visualisation (dans l'onglet Visualisation)
            # ==========================================================
     
            # Si des images PNG d'une fiche prof, ou d'une fiche
            # élève, ou d'une fiche d'évaluation existe déjà, 
            # elles sont éliminées avant d'en recréer d'autres
     
            # On liste le contenu du répertoire temporaire ...
            liste_contenu_tmp = os.listdir(tempfile.gettempdir())
            # ... ou du répertoire courant ...
            liste_contenu_rep_courant = os.listdir(os.getcwd())
     
            # ------------------------------------------------------------
            # Exception pour contrôler le répertoire temporaire utilisé
            # ------------------------------------------------------------
            try :
                for contenu in liste_contenu_tmp :
                    # Si le fichier tempo concerné est bien dedans ...
                    if 'pdf_png_apsc' in contenu :
                        APSC_Print("Le fichier temporaire contient déjà des fiches (prof, élève ou évaluation) ; le fichier {} est éliminé".format(contenu))
                        APSC_Print(" ")
                        os.remove(tempfile.gettempdir()+os.sep+contenu)
            except :
                for contenu in liste_contenu_rep_courant :
                    if 'pdf_png_apsc' in contenu :
                        APSC_Print("Le fichier temporaire contient déjà des fiches (prof, élève ou évaluation) ; le fichier {} est éliminé".format(contenu))
                        APSC_Print(" ")
                        os.remove(os.getcwd()+os.sep+contenu)        
     
            # Chemin et nom de fichier du fichier PDF à traiter
            pdf_traitement = optio_2[0]
            # Chemin (dans le répertoire temporaire) et nom des images (PNG)
            img_traitement = tempfile.gettempdir()+os.sep+'pdf_png_apsc'
            # Sous windows ... 
            if os.name == 'nt' :
                import subprocess
                # ... on utilise directement l'exécutable pdftoppm.exe
                # (se trouvant ds le répertoire racine (courant))
                pdftoppm_executable = "pdftoppm.exe"
                # La commande ...
                commande = "{} -r 96 -png -aa yes {} {}".format(pdftoppm_executable, pdf_traitement, img_traitement)
                #
                subprocess.call(commande, shell = True)
            # Sous GNU/Linux ...    
            else : 
                # On utilise le module pdf2image ... installé par 
                # la commande : pip3 install pdf2image
                from pdf2image import convert_from_path
                pages = convert_from_path(pdf_traitement, 96)
                for n, page in enumerate(pages) :
                    page.save(img_traitement+'-'+str(n+1)+'.png', 'PNG')
            # ==========================================================
     
            # Visionnage des séquences prof et élève
            from affichage_apsc.visionnage_gui import Visionnage ##############
            visio = Visionnage(parent=None) ################
     
    ...
    Comme cette classe est exécutée dans un premier temps dans le script main, il faudrait que je vérifie si les images PNG présentes dans le répertoire temporaire (c'est à dire les fichiers PDF convertis en images PNG) ont été modifiées après l'appel de cette classe. Il faudrait sans doute que je le fasse avec os.stat ... comment faire une statistique des images avant le traitement et après le traitement ? Comment modifier cette classe Visionnage pour cela ?

    La classe Visionnage après-coup :

    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
    import os, tempfile
     
    # Imports PyQt5 -----------------------------------------------------------------------
    from PyQt5.QtWidgets import QWidget, QGroupBox, QPushButton, QGridLayout, \
                                QGraphicsScene, QGraphicsView, QGraphicsPixmapItem, \
                                QApplication
    from PyQt5.QtCore import QSize, Qt, QTimer
    from PyQt5.QtGui import QPixmap, QIcon
    # --------------------------------------------------------------------------------------
     
     
    class Visionnage(QWidget):
        ''' Classe pour visionner le résultat (en images PNG de chaque 
        page en PDF) des fiches prof, élève ou évaluation, selon les cas '''
     
        def __init__(self, parent=None):
            super(Visionnage, self).__init__(parent)
     
            # Utilisation QGraphicsScene et QGraphicsView
            self.scene  = QGraphicsScene()
            self.graphique_vue = QGraphicsView(self.scene)
     
            # On liste le contenu du répertoire temporaire ...
            liste_contenu_tmp = os.listdir(tempfile.gettempdir())
            # ... ou du répertoire courant ...
            liste_contenu_rep_courant = os.listdir(os.getcwd())
     
            # liste pur accueillir toutes les 
            # images (PDF transformés en PNG)
            self.liste_images = []
     
            # ------------------------------------------------------------
            # Exception pour contrôler le répertoire temporaire utilisé
            # ------------------------------------------------------------
            try :
                # Boucle de vérif ...
                for contenu in liste_contenu_tmp :
                    # Si le fichier tempo concerné est bien dedans ...
                    if 'pdf_png_apsc' in contenu :
                        # ... la liste est remplie avec le chemin complet
                        self.liste_images.append(tempfile.gettempdir()+os.sep+contenu)
            except :
                for contenu in liste_contenu_rep_courant :
                    if 'pdf_png_apsc' in contenu :
                        self.liste_images.append(os.getcwd()+os.sep+contenu)
     
            # Icône pour le bouton ...
            icone = QIcon(os.path.join('logo_png_apsc', 'icone_visualisation_apsc_256x256.png'))            
     
            # =====================================================
            groupe_1 = QGroupBox()
            groupe_2 = QGroupBox()
     
            grid_1 = QGridLayout()
            grid_1.setSpacing(10)
     
            grid_2 = QGridLayout()
            grid_2.setSpacing(10)
     
            # Ajout du QGraphicsView ds la grille 1
            grid_1.addWidget(self.graphique_vue, 0, 0)
     
            print("len(self.liste_images)", len(self.liste_images))
     
            # Boucle pour lister le nombre d'images et
            # attribuer les boutons en conséquence
            for n, i in enumerate(self.liste_images) :
     
                print("Image tempo {}".format(n), i)
     
                # Bouton pour ajouter une ligne pour les questions d'enseignement
                self.bout_visio = PushButtonIconeGauche("Vue page {}".format(n+1), icon = icone, iconSize = QSize(16, 16))
     
                # Ajout du ou des bouton(s) dans la grille 2
                grid_2.addWidget(self.bout_visio, 0, n)
     
                QApplication.processEvents() #########
     
                # ==========================================
                # Signal (différentes situations pour les 
                # boutons ... suivant le nombre d'images)
                # ==========================================
                # Affichage de 20 pages possibles
                if n == 0 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(0))
                elif n == 1 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(1))
                elif n == 2 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(2))
                elif n == 3 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(3))
                elif n == 4 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(4))
                elif n == 5 : 
                    self.bout_visio.clicked.connect(lambda: self.afficher(5))
     
            #
            grid_1.setAlignment(Qt.AlignVCenter)
            #
            groupe_1.setLayout(grid_1)
            groupe_2.setLayout(grid_2)
     
            layout = QGridLayout()
            layout.addWidget(groupe_1, 0, 0)
            layout.addWidget(groupe_2, 1, 0)
            #
            self.setLayout(layout)
            # =====================================================
     
     
        def afficher(self, n) :
            ''' Fonction pour afficher une image PNG de la fiche 
            prof, de la fiche élève (ou de la fiche d'évaluation), 
            en cours '''
     
            self.scene.clear() ##########
            self.graphique_vue.items().clear() ##########
     
            images = self.liste_images[n]
            pixmap = QPixmap(images)
            item   = QGraphicsPixmapItem(pixmap)
            self.scene.addItem(item)
            self.graphique_vue.setScene(self.scene)
            #
            self.graphique_vue.show()
    Si j'utilise os.stat, que dois-je vérifier ?

    Comment procéder ?

  3. #3
    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,

    Il faudrait poser des questions plus précises qui n'obligent pas les personnes qui peuvent aider à lire 200 lignes de code.

    J'interviens seulement sur un point. Pour consulter un pdf, c'est dommage de le convertir en image. En effet, une fois convertis, les zooms d'affichage se traduisent par des escaliers moches, alors que les pdf contiennent des polices et des images vectorielles.

    Curieusement, PyQt5 sait créer des fichiers pdf, mais ne sait pas les afficher. On dit que les prochaines versions le permettront, mais on peut déjà actuellement au moins avec ces 2 méthodes:

    1- passer la main au lecteur de pdf par défaut de l'OS avec QtGui.QDesktopServices (par exemple un adobe reader installé sous Windows et déclaré comme lecteur pdf par défaut)

    2- utiliser pdf.js (https://mozilla.github.io/pdf.js/) avec un QtWebEngineWidgets.QWebEngineView. J'ai donné un exemple ici: https://www.developpez.net/forums/d1.../#post10373777

    Par ailleurs, si besoin, les pdf peuvent être découpés en pages et regroupés (="split and merge") avec PyPDF2 (https://pypi.org/project/PyPDF2/)
    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

  4. #4
    Membre à l'essai
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Points : 17
    Points
    17
    Par défaut
    Bonsoir tyrtamos,

    Désolé pour la réponse tardive ...

    Citation Envoyé par tyrtamos Voir le message
    Bonjour,
    Il faudrait poser des questions plus précises qui n'obligent pas les personnes qui peuvent aider à lire 200 lignes de code.
    Oui effectivement, la prochaine fois je ferais mieux ...

    J'interviens seulement sur un point. Pour consulter un pdf, c'est dommage de le convertir en image. En effet, une fois convertis, les zooms d'affichage se traduisent par des escaliers moches, alors que les pdf contiennent des polices et des images vectorielles.

    Curieusement, PyQt5 sait créer des fichiers pdf, mais ne sait pas les afficher. On dit que les prochaines versions le permettront, mais on peut déjà actuellement au moins avec ces 2 méthodes:

    1- passer la main au lecteur de pdf par défaut de l'OS avec QtGui.QDesktopServices (par exemple un adobe reader installé sous Windows et déclaré comme lecteur pdf par défaut)

    2- utiliser pdf.js (https://mozilla.github.io/pdf.js/) avec un QtWebEngineWidgets.QWebEngineView. J'ai donné un exemple ici: https://www.developpez.net/forums/d1.../#post10373777

    Par ailleurs, si besoin, les pdf peuvent être découpés en pages et regroupés (="split and merge") avec PyPDF2 (https://pypi.org/project/PyPDF2/)
    Je n'ai pas encore regardé QtGui.QDesktopServices.

    pdf.js et la solution que tu donnes pour son utilisation parait très très intéressant, en tous les cas j'apprends des choses ...

    Entre temps j'ai trouvé une solution (qui vaut ce qu'elle vaut ; en utilisant Pillow et Numpy pour le traitement des pages pdf transformées en images) ... les différentes pages (les images) sont fondues verticalement en une seule image qui est à la fin visualisée. J'ai aussi implémenté un zoom +, un zoom -, et on peut aussi revenir à l'affichage par défaut (en utilisant : self.graphique_vue.setTransform(QtGui.QTransform()) ).

    Pour l'effet d'escalier causé par les zoom avant et arrière, j'ai aussi trouvé la solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ...
            pixmap = QPixmap(images)
            item   = QGraphicsPixmapItem(pixmap)
     
            # Amélioration de la qualité
            item.setTransformationMode(Qt.SmoothTransformation)
     
    ...
    J'ai mis 2 images du résultat (en situation) dans mon application.

    Autrement j'ai une amélioration à mettre en place, je ne sais pas encore comment y arriver, ... il faut que je trouve le moyen de le formuler de façon simple.

    a+
    Images attachées Images attachées   

Discussions similaires

  1. [2008] Problème affichage attribut table de fait dans un cube
    Par cana13 dans le forum SSAS
    Réponses: 6
    Dernier message: 01/04/2013, 12h50
  2. affichage des attributs d'une classe
    Par dolsky dans le forum VB.NET
    Réponses: 9
    Dernier message: 02/06/2009, 15h13
  3. Problème de contrôle d'un attribut de classe
    Par 30barrett40 dans le forum C++
    Réponses: 3
    Dernier message: 13/03/2007, 11h00
  4. Problème avec l'attribut class
    Par Marty000 dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 20/11/2006, 08h51
  5. [css]problème d'attribution de classe dans deux listes
    Par Mitaka dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 24/11/2005, 18h05

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