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 :

Document multipage (multi-scène, multi-vue ?)


Sujet :

PyQt Python

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

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Par défaut Document multipage (multi-scène, multi-vue ?)
    Bonjour à tous,

    Dans une scène et une vue associée, je dispose, ajoute, supprime, bouge redimensionne des items (panneaux/rectangles, textes, ...) ; là rien de bien difficile.

    Ce qui me pose problème est que je voudrais travailler sur plusieurs pages (plusieurs scènes, plusieurs vues ?).
    J'ai fait un script ultra basique pour argumenter ma demande. Dans ce script je crée des pages à partir du combo et je voudrais associer chaque page créé à une nouvelle scène/vue afin de produire un document final multipage (autant que possible).

    Les différentes pages/vues/scènes correspondraient en quelque sorte à des calques (qui se superposeraient les uns les autres). Sur les différentes pages on aurait bien entendu la possibilité de disposer des items (panneaux/rectangles, textes, ...) ... et en naviguant entre les pages (par l'intermédiaire du combo), on pourrait rajouter/enlever/traiter les items.

    Je me pose la question quant à la stratégie à mettre en place pour y arriver, avez-vous des idées ?, des exemples à montrer ?

    J'espère que vous pourrez m'aider.

    Bonne journée, bon week-end.

    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
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    # Imports PyQt5 -----------------------------------------------------------------------
    from PyQt5.QtCore import (Qt, QRectF)
    from PyQt5.QtWidgets import (QPushButton, QWidget, QVBoxLayout, QSpinBox, QLabel, 
                                 QComboBox, QHBoxLayout, QGraphicsScene, QGraphicsView, 
                                 QSlider, QGraphicsPixmapItem, QApplication, QGraphicsItem)
    from PyQt5.QtGui import (QColor, QBrush, QPixmap, QTransform, QPen, QPainterPath, QPainter)
    # ------------------------------------------------------------------------------------
     
    import sys, os
     
    class GraphiqueScene(QGraphicsScene) :
     
        def __init__(self, parent = None) :
            super(GraphiqueScene, self).__init__(parent)
     
     
    class GraphiqueVue(QGraphicsView) :
     
        backgroundcolor = QColor(100, 100, 100)
     
        def __init__(self, parent = None) :
            super(GraphiqueVue, self).__init__(parent)
     
            self.setBackgroundBrush(self.backgroundcolor)
     
            self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing)
            self.setRenderHint(QPainter.TextAntialiasing)
            self.setDragMode(QGraphicsView.RubberBandDrag)
     
     
    class GraphiqueMain(QWidget):
        def __init__(self):
            super(GraphiqueMain, self).__init__()
     
            self.setWindowTitle("Demande d'aide pour multipage/multiscènes")
     
            self.setGeometry(20, 40, 1200, 760)
            self.setMinimumSize(1200, 760)
     
     
            bout_ajouter_page = QPushButton("Ajouter page")
            bout_supprimer_page = QPushButton("Supprimer page")
            bout_ajout_panneau = QPushButton("Ajouter panneau")
            bout_supp_panneau = QPushButton("Supprimer panneau")
            bout_taille_adaptee = QPushButton("Taille adaptée")
     
            liste_pages = ["Page 1"]
            self.combo_pages = QComboBox()
            for page in liste_pages :
                self.combo_pages.addItem(page)
            self.combo_pages.setMinimumHeight(28)
     
            self.slider_redimensionnement = QSlider()
            self.slider_redimensionnement.setOrientation(Qt.Horizontal)
            self.slider_redimensionnement.setMinimum(100)
            self.slider_redimensionnement.setMaximum(3000)
            self.slider_redimensionnement.setValue(500)
            self.slider_redimensionnement.setSingleStep(1)
            self.slider_redimensionnement.setFixedWidth(150)
     
            # --------------------------------------------
            self.scene  = QGraphicsScene()
            self.graphique_vue = GraphiqueVue(self.scene)
            # --------------------------------------------
     
            # Ici mettre une image à charger
            self.affichage_vue('./page_blanche_portrait_150_dpi_1240x1754.png')
     
            hbox_1 = QHBoxLayout()
            hbox_1.addWidget(self.graphique_vue)
            #
            vbox_1 = QVBoxLayout()
            vbox_1.addWidget(bout_ajouter_page)
            vbox_1.addWidget(bout_supprimer_page)
            vbox_1.addWidget(QLabel("Pages à sélectionner :"))
            vbox_1.addWidget(self.combo_pages)
            vbox_1.addWidget(bout_ajout_panneau)
            vbox_1.addWidget(bout_supp_panneau)
            vbox_1.addWidget(QLabel("Redimensionner :"))
            vbox_1.addWidget(self.slider_redimensionnement)
            vbox_1.addWidget(bout_taille_adaptee)
            #
            vbox_1.setAlignment(Qt.AlignVCenter)
            #
            hbox_layout = QHBoxLayout()
            hbox_layout.addLayout(hbox_1)
            hbox_layout.addLayout(vbox_1)
            #hbox_layout.setStretch(0, 1)
            #
            self.setLayout(hbox_layout)
     
            # Signaux
            bout_ajouter_page.clicked.connect(self.ajouter_page)
            self.combo_pages.currentIndexChanged.connect(self.afficher_num_page)
            bout_supprimer_page.clicked.connect(self.supprimer_page)
            bout_ajout_panneau.clicked.connect(self.ajouter_panneau)
            bout_supp_panneau.clicked.connect(self.supprimer_item)
            self.slider_redimensionnement.valueChanged.connect(self.redimensionner_selection)
            bout_taille_adaptee.clicked.connect(self.afficher_zoom_taille_adaptee)
     
     
        def affichage_vue(self, image) :
            pixmap = QPixmap(image)
            item = QGraphicsPixmapItem(pixmap)
            item.setTransformationMode(Qt.SmoothTransformation)
            self.scene.addItem(item)
            self.graphique_vue.setScene(self.scene)
            x, y = 0, 0
            self.scene.setSceneRect(0, 0, pixmap.width(), pixmap.height())
            self.graphique_vue.centerOn(x, y)
            self.graphique_vue.setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
            self.graphique_vue.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
            self.graphique_vue.update()
     
     
        def ajouter_page(self) :
            self.combo_pages.addItem("Page {}".format(self.combo_pages.count() + 1))
     
     
        def supprimer_page(self) :
            if self.combo_pages.count() > 1 :
                self.combo_pages.removeItem(self.combo_pages.currentIndex())
     
     
        def afficher_num_page(self) :
            print("Index sélectionné : {}".format(self.combo_pages.currentIndex()))
     
     
        def ajouter_panneau(self) :
            contour = QPen(QColor(0, 0, 0, 255), 15)
            contour.setStyle(Qt.DotLine)
            contour.setCapStyle(Qt.RoundCap)
            contour.setJoinStyle(Qt.RoundJoin)
            chemin = QPainterPath()
            chemin.addRoundedRect(QRectF(10, 10, 740, 200), 30, 30)
            rectangle = self.scene.addPath(chemin, pen = contour, brush = QBrush(QColor(120, 136, 145, 160)))
            rectangle.setFlag(QGraphicsItem.ItemIsMovable)
            rectangle.setFlag(QGraphicsItem.ItemIsSelectable)
     
     
        def supprimer_item(self) :
            print(self.graphique_vue.scene().selectedItems())
            #for item in self.scene.selectedItems() :
            for item in self.graphique_vue.scene().selectedItems() :
                self.scene.removeItem(item)
                del item
     
     
        def redimensionner_selection(self, valeur) :
            for item in self.scene.selectedItems() :
                transform = QTransform()
                transform.scale(valeur/1000, valeur/1000)
                item.setTransform(transform)
                self.update()
     
     
        def afficher_zoom_taille_adaptee(self) :
            self.graphique_vue.setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
            self.graphique_vue.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
     
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = GraphiqueMain()
        ex.show()
        sys.exit(app.exec_())

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 305
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 305
    Par défaut
    Salut,

    J'ai créé un module d'impression (dans le sens imprimer) qui permet de créer des pdf multipages avec navigation entre les diverses pages.

    Tout est ici: https://bazaar.launchpad.net/~vincen...head:/printing

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

    Au cas où, j'ai donné ce que j'utilise pour générer des pdf multipages avec en-tête et bas de page:

    https://www.developpez.net/forums/d1.../#post11712915

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

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Par défaut
    Bonjour VinsS et tyrtamos,

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

    @VinsS et @tyrtamos : je ne cherche pas à "créer des pdf multipages avec navigation entre les diverses pages", je me suis certainement mal exprimé dans ma demande (et le titre porte peut-être à confusion). Je cherche à pouvoir accéder à plusieurs pages en utilisant QGraphicsScene et QGraphicsView (plusieurs scènes/vues sélectionnables à la demande). J'en suis pour l'instant à l'affichage et non encore à la restitution. Je voudrais pouvoir disposer des items dans les différents pages (en convoquant diverses scènes ... et vues (?)). J'ai retravaillé mon script et maintenant les dictionnaires self.dico_scenes et self.dico_vues s'incrémentent à chaque fois que je crée une nouvelle page. Je voudrais afficher la nouvelle page juste après l'avoir crée, pouvoir y déposer des items, et pouvoir (par l'intermédiaire du combo) afficher la page correspondante quand je la sélectionne (bien entendu avec les items qui ont été précédemment ajoutés, après coup). Voilà mon script retravaillé (bon il est en bazard pour l'instant, mais compréhensible, enfin j'espère) :

    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
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    # Imports PyQt5 -----------------------------------------------------------------------
    from PyQt5.QtCore import (Qt, QRectF)
    from PyQt5.QtWidgets import (QPushButton, QWidget, QVBoxLayout, QSpinBox, QLabel, 
                                 QComboBox, QHBoxLayout, QGraphicsScene, QGraphicsView, 
                                 QSlider, QGraphicsPixmapItem, QApplication, QGraphicsItem)
    from PyQt5.QtGui import (QColor, QBrush, QPixmap, QTransform, QPen, QPainterPath, QPainter, QImage) # QImage
    # ------------------------------------------------------------------------------------
     
    import sys, os
     
    class GraphiqueScene(QGraphicsScene) :
     
        def __init__(self, imageFile = None, parent = None) :
            super(GraphiqueScene, self).__init__(parent)
            self.imageFile = imageFile ###################
            self.background = None ####################
     
     
    class GraphiqueVue(QGraphicsView) :
     
        backgroundcolor = QColor(100, 100, 100)
     
        def __init__(self, parent = None) :
            super(GraphiqueVue, self).__init__(parent)
     
            self.setBackgroundBrush(self.backgroundcolor)
     
            self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing)
            self.setRenderHint(QPainter.TextAntialiasing)
            self.setDragMode(QGraphicsView.RubberBandDrag)
     
     
    class GraphiqueMain(QWidget):
        def __init__(self):
            super(GraphiqueMain, self).__init__()
     
            # -----------------------
            # Dictionnaire ...
            # -----------------------
            self.dico_scenes = {}
            # -----------------------
            # Dictionnaire ...
            # -----------------------
            self.dico_vues = {}
            # -----------------------
     
            self.setWindowTitle("Demande d'aide pour multipage/multiscènes")
     
            self.setGeometry(20, 40, 1200, 760)
            self.setMinimumSize(1200, 760)
     
            self.bout_ajouter_page = QPushButton("Ajouter page")
            self.bout_supprimer_page = QPushButton("Supprimer page")
            self.bout_ajout_panneau = QPushButton("Ajouter panneau")
            self.bout_supp_panneau = QPushButton("Supprimer panneau")
            self.bout_taille_adaptee = QPushButton("Taille adaptée")
     
            self.label_pages = QLabel("Pages à sélectionner :")
            self.label_redimensionner = QLabel("Redimensionner :")
     
            liste_pages = ["Page 1"]
            self.combo_pages = QComboBox()
            for page in liste_pages :
                self.combo_pages.addItem(page)
            self.combo_pages.setMinimumHeight(28)
     
            self.slider_redimensionnement = QSlider()
            self.slider_redimensionnement.setOrientation(Qt.Horizontal)
            self.slider_redimensionnement.setMinimum(100)
            self.slider_redimensionnement.setMaximum(3000)
            self.slider_redimensionnement.setValue(500)
            self.slider_redimensionnement.setSingleStep(1)
            self.slider_redimensionnement.setFixedWidth(150)
     
            # Appel de la fonction de récupération de la scène et de la vue
            self.scene, self.graphique_vue = self.fonction_appel_scene_vue()
     
            # Ici mettre une image à charger
            self.affichage_vue('./page_blanche_portrait_150_dpi_1240x1754.png')
     
            """
            self.hbox_1 = QHBoxLayout()
            self.hbox_1.addWidget(self.graphique_vue)
            """
            #
            self.hbox_1 = self.hbox_graphique_vue()
     
            #
            self.vbox_1 = QVBoxLayout()
            self.vbox_1.addWidget(self.bout_ajouter_page)
            self.vbox_1.addWidget(self.bout_supprimer_page)
            self.vbox_1.addWidget(self.label_pages)
            self.vbox_1.addWidget(self.combo_pages)
            self.vbox_1.addWidget(self.bout_ajout_panneau)
            self.vbox_1.addWidget(self.bout_supp_panneau)
            self.vbox_1.addWidget(self.label_redimensionner)
            self.vbox_1.addWidget(self.slider_redimensionnement)
            self.vbox_1.addWidget(self.bout_taille_adaptee)
            #
            self.vbox_1.setAlignment(Qt.AlignVCenter)
            #
            self.hbox_layout = QHBoxLayout()
            self.hbox_layout.addLayout(self.hbox_1)
            self.hbox_layout.addLayout(self.vbox_1)
            #
            self.setLayout(self.hbox_layout)
     
            # Signaux
            self.bout_ajouter_page.clicked.connect(self.ajouter_page)
            self.combo_pages.currentIndexChanged.connect(self.afficher_page)
            self.bout_supprimer_page.clicked.connect(self.supprimer_page)
            self.bout_ajout_panneau.clicked.connect(self.ajouter_panneau)
            self.bout_supp_panneau.clicked.connect(self.supprimer_item)
            self.slider_redimensionnement.valueChanged.connect(self.redimensionner_selection)
            self.bout_taille_adaptee.clicked.connect(self.afficher_zoom_taille_adaptee)
     
     
        #####################################################
        def hbox_graphique_vue(self) :
            _, self.graphique_vue = self.capture_scene_vue()
            hbox = QHBoxLayout()
            hbox.addWidget(self.graphique_vue)
            return hbox
        #####################################################
     
     
        def capture_scene_vue(self) :
            # Index de la page sélectionnée
            index = self.afficher_page()
            # Scene sélectionnée par son index
            scene = list(self.dico_scenes.values())[index]
            # Vue sélectionnée par son index
            vue = list(self.dico_vues.values())[index]
            return scene, vue
     
     
        def affichage_vue(self, image) :
            # Récup de la scène et la vue en cours
            self.scene, self.graphique_vue = self.capture_scene_vue()
     
            pixmap = QPixmap(image)
            item = QGraphicsPixmapItem()
            item.setPixmap(pixmap)
            item.setTransformationMode(Qt.SmoothTransformation)
            #item.setZValue(0)
            z = item.zValue()
            print("zValue item", z)
            self.scene.addItem(item)
            self.graphique_vue.setScene(self.scene)
            x, y = 0, 0
            self.scene.setSceneRect(0, 0, pixmap.width(), pixmap.height())
            self.graphique_vue.centerOn(x, y)
            self.graphique_vue.setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
            self.graphique_vue.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
     
            #
            index = self.afficher_page()
            print("SCENE (dans fonction) affichage_vue de la page {} à l'index {} : {}".format(index+1, index, self.scene))
            print("VUE (dans fonction) affichage_vue de la page {} à l'index {} : {}".format(index+1, index, self.graphique_vue))
            print("# --------------------------------------- ")
     
            #
            self.graphique_vue.update()
     
     
        def fonction_appel_scene_vue(self) :
            # --------------------------------------------
            scenes  = QGraphicsScene()
            vues = GraphiqueVue(scenes)
            # --------------------------------------------
            nbre_pages = self.combo_pages.count()
            self.dico_scenes[nbre_pages - 1] = scenes
            self.dico_vues[nbre_pages - 1] = vues
            print("self.dico_scenes", self.dico_scenes)
            print("self.dico_vues", self.dico_vues)
            print("# --------------------------------------- ")
            # On récupère le nombre de scènes ajoutées à l'instant
            # t (par l'intermédiaire des clés du dictionnaire)
            nbre_elements_dico_scene = len(list(self.dico_scenes.keys()))
            # On récupère le nombre de vues ajoutées à l'instant
            # t (par l'intermédiaire des clés du dictionnaire)
            nbre_elements_dico_vue = len(list(self.dico_vues.keys()))
            print("Nbre d'éléments ds le dico scènes", list(self.dico_scenes.keys()))
            print("Nbre d'éléments ds le dico vues", len(list(self.dico_vues.keys())))
            # Dernier élément rajouté (dernière scène du dictionnaire)
            scenes_dico = list(self.dico_scenes.values())[nbre_elements_dico_scene - 1]
            # Dernier élément rajouté (dernière vue du dictionnaire)
            vues_dico = list(self.dico_vues.values())[nbre_elements_dico_vue - 1]
            print("scenes_dico DERNIER élément", scenes_dico)
            print("vues_dico DERNIER élément", vues_dico)
            print("# --------------------------------------- ")
            return scenes_dico, vues_dico
     
     
        def ajouter_page(self) :
            self.combo_pages.addItem("Page {}".format(self.combo_pages.count() + 1))
            print("# --------------------------------------- ")
     
            # MAJ (au moment de la sélection 
            # des pages par le combo)
            self.fonction_appel_scene_vue()
     
            self.scene, self.graphique_vue = self.capture_scene_vue()
     
            # MAJ !!!
            self.affichage_vue('./page_blanche_portrait_150_dpi_1240x1754.png')
     
     
        def supprimer_page(self) :
            if self.combo_pages.count() > 1 :
                self.combo_pages.removeItem(self.combo_pages.currentIndex())
     
     
        def afficher_page(self) :
            print("Index sélectionné : {}".format(self.combo_pages.currentIndex()))
            print("# ======================================= ")
            index = self.combo_pages.currentIndex()
            return index
     
     
        def ajouter_panneau(self) :
            #
            self.scene, _ = self.capture_scene_vue()
     
            contour = QPen(QColor(0, 0, 0, 255), 15)
            contour.setStyle(Qt.DotLine)
            contour.setCapStyle(Qt.RoundCap)
            contour.setJoinStyle(Qt.RoundJoin)
            chemin = QPainterPath()
            chemin.addRoundedRect(QRectF(10, 10, 740, 200), 30, 30)
            rectangle = self.scene.addPath(chemin, pen = contour, brush = QBrush(QColor(120, 136, 145, 160)))
            rectangle.setFlag(QGraphicsItem.ItemIsMovable)
            rectangle.setFlag(QGraphicsItem.ItemIsSelectable)
     
     
        def supprimer_item(self) :
            #
            self.scene, _ = self.capture_scene_vue()
     
            for item in self.scene.selectedItems() :
                self.scene.removeItem(item)
                del item
     
     
        def redimensionner_selection(self, valeur) :
            #
            self.scene, _ = self.capture_scene_vue()
     
            for item in self.scene.selectedItems() :
                transform = QTransform()
                transform.scale(valeur/1000, valeur/1000)
                item.setTransform(transform)
                self.update()
     
     
        def afficher_zoom_taille_adaptee(self) :
            #
            self.scene, self.graphique_vue = self.capture_scene_vue()
     
            self.graphique_vue.setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
            self.graphique_vue.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
     
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = GraphiqueMain()
        ex.show()
        sys.exit(app.exec_())
    Voilà les prints (pour vérifier), et ça déconne, ... les nouvelles scènes et vues ne sont pas affichées dans le vue principale (seulement la 1ère scène est désespérément affichée) et quand je crée (à chaque fois) une nouvelle page, je voudrais quelle vienne par dessus la page d'avant (en gardant les items), en fait comme pour des calques. Ici j'ai ajouté un panneau sur la page 1, ajouté une page --> bouton Ajouter page (c'est la page 2 dans le combo), ajouté un panneau, ... ainsi de suite ... Il y a en tout 4 pages. Je m'aperçois que les pages 2, 3 et 4 ne sont pas affichées dans la vue. Suis-je complètement à côté de la plaque dans ce que je suis en train de faire ?

    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
    self.dico_scenes {0: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>}
    self.dico_vues {0: <__main__.GraphiqueVue object at 0x0000018C44079F78>}
    # --------------------------------------- 
    Nbre d'éléments ds le dico scènes [0]
    Nbre d'éléments ds le dico vues 1
    scenes_dico DERNIER élément <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>
    vues_dico DERNIER élément <__main__.GraphiqueVue object at 0x0000018C44079F78>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    zValue item 0.0
    Index sélectionné : 0
    # ======================================= 
    SCENE (dans fonction) affichage_vue de la page 1 à l'index 0 : <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>
    VUE (dans fonction) affichage_vue de la page 1 à l'index 0 : <__main__.GraphiqueVue object at 0x0000018C44079F78>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 0
    # ======================================= 
    # --------------------------------------- 
    self.dico_scenes {0: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>, 1: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085798>}
    self.dico_vues {0: <__main__.GraphiqueVue object at 0x0000018C44079F78>, 1: <__main__.GraphiqueVue object at 0x0000018C44085558>}
    # --------------------------------------- 
    Nbre d'éléments ds le dico scènes [0, 1]
    Nbre d'éléments ds le dico vues 2
    scenes_dico DERNIER élément <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085798>
    vues_dico DERNIER élément <__main__.GraphiqueVue object at 0x0000018C44085558>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 0
    # ======================================= 
    zValue item 0.0
    Index sélectionné : 0
    # ======================================= 
    SCENE (dans fonction) affichage_vue de la page 1 à l'index 0 : <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>
    VUE (dans fonction) affichage_vue de la page 1 à l'index 0 : <__main__.GraphiqueVue object at 0x0000018C44079F78>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    # --------------------------------------- 
    self.dico_scenes {0: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>, 1: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085798>, 2: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C440858B8>}
    self.dico_vues {0: <__main__.GraphiqueVue object at 0x0000018C44079F78>, 1: <__main__.GraphiqueVue object at 0x0000018C44085558>, 2: <__main__.GraphiqueVue object at 0x0000018C44085948>}
    # --------------------------------------- 
    Nbre d'éléments ds le dico scènes [0, 1, 2]
    Nbre d'éléments ds le dico vues 3
    scenes_dico DERNIER élément <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C440858B8>
    vues_dico DERNIER élément <__main__.GraphiqueVue object at 0x0000018C44085948>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 0
    # ======================================= 
    zValue item 0.0
    Index sélectionné : 0
    # ======================================= 
    SCENE (dans fonction) affichage_vue de la page 1 à l'index 0 : <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>
    VUE (dans fonction) affichage_vue de la page 1 à l'index 0 : <__main__.GraphiqueVue object at 0x0000018C44079F78>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    # --------------------------------------- 
    self.dico_scenes {0: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>, 1: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085798>, 2: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C440858B8>, 3: <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085DC8>}
    self.dico_vues {0: <__main__.GraphiqueVue object at 0x0000018C44079F78>, 1: <__main__.GraphiqueVue object at 0x0000018C44085558>, 2: <__main__.GraphiqueVue object at 0x0000018C44085948>, 3: <__main__.GraphiqueVue object at 0x0000018C44085E58>}
    # --------------------------------------- 
    Nbre d'éléments ds le dico scènes [0, 1, 2, 3]
    Nbre d'éléments ds le dico vues 4
    scenes_dico DERNIER élément <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44085DC8>
    vues_dico DERNIER élément <__main__.GraphiqueVue object at 0x0000018C44085E58>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 0
    # ======================================= 
    zValue item 0.0
    Index sélectionné : 0
    # ======================================= 
    SCENE (dans fonction) affichage_vue de la page 1 à l'index 0 : <PyQt5.QtWidgets.QGraphicsScene object at 0x0000018C44079EE8>
    VUE (dans fonction) affichage_vue de la page 1 à l'index 0 : <__main__.GraphiqueVue object at 0x0000018C44079F78>
    # --------------------------------------- 
    Index sélectionné : 0
    # ======================================= 
    Index sélectionné : 1
    # ======================================= 
    Index sélectionné : 2
    # ======================================= 
    Index sélectionné : 3
    # =======================================
    Une autre solution serait peut-être d'assigner et de faire afficher diverses scène/vues par un QStackedWidget, avec 1 widget "englobant" et une fonction par page/calque, mais je voudrais encore explorer ce que je suis en train de faire (et voir si ça peut fonctionner). Il y aurait éventuellement aussi cette solution --> la partie QGraphicsItemLayer (à voir).

    Pouvez-vous m'aider ? (j'espère que ma demande est suffisamment claire).

    A bientôt.

  5. #5
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 305
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 305
    Par défaut
    Ta méthode afficher_page ne fait que retourner l'index de la page demandée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            ...
            self.combo_pages.currentIndexChanged.connect(self.afficher_page)
     
        def afficher_page(self) :
            print("Index sélectionné : {}".format(self.combo_pages.currentIndex()))
            print("# ======================================= ")
            index = self.combo_pages.currentIndex()
            return index
    ... ce qui ne mène pas très loin.

    En fait j'avais bien compris ta question. Je t'ai proposé d'analyser mon code qui lui n'utilise qu'une seule vue.

    On peut naviguer entre les différentes pages, les modifier et, en plus de créer un pdf multipages, on peut enregistrer le travail en cours pour le reprendre plus tard.

    Si tu veux utiliser une vue par page, alors le QStackedWidget sera approprié.

  6. #6
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2017
    Messages
    30
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2017
    Messages : 30
    Par défaut
    Bonjour VinS, bonjour à tous,

    Réponse très tardive ...

    Citation Envoyé par VinsS Voir le message
    Ta méthode afficher_page ne fait que retourner l'index de la page demandée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            ...
            self.combo_pages.currentIndexChanged.connect(self.afficher_page)
     
        def afficher_page(self) :
            print("Index sélectionné : {}".format(self.combo_pages.currentIndex()))
            print("# ======================================= ")
            index = self.combo_pages.currentIndex()
            return index
    ... ce qui ne mène pas très loin.
    Oui effectivement !, ça m'avait complètement échappé .

    En fait j'avais bien compris ta question. Je t'ai proposé d'analyser mon code qui lui n'utilise qu'une seule vue.

    On peut naviguer entre les différentes pages, les modifier et, en plus de créer un pdf multipages, on peut enregistrer le travail en cours pour le reprendre plus tard.
    Je vais le faire pendant les vacances scolaires ; je suis prof, pas du tout dans une matière qui a quelque chose à voir avec l'informatique, je ne suis donc pas du tout dans mon domaine de compétences.

    Si tu veux utiliser une vue par page, alors le QStackedWidget sera approprié.
    En fait j'ai choisi une solution différente ; par un QListWidget et un mini panneau associé qui me permet d'ajouter des pages, les supprimer, le monter, les descendre, les sélectionner par un combo et les éliminer d'un coup.

    Ca fonctionne (bon je ne suis pas un expert, c'est clair !). J'ai tout de même un souci, c'est que je veux adapter le widget englobant de la Scène/Vue à l'espace réservé au QListWidget (et qu'il puisse se redimensionner automatiquement) si je redimensionne la fenêtre. Pour l'instant (voir la fonction : recalcul_resolution_scene, et les lignes (212, 216) : hauteur_scene = self.recalcul_resolution_scene() et itemGraph.setSizeHint(QSize(itemGraph.sizeHint().width(), hauteur_scene))), ça fonctionne qu'à moitié, en tous cas je ne suis pas satisfait de cette partie, ... comment faire ?

    Voici le code :

    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
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    # Imports PyQt5 -----------------------------------------------------------------------
    from PyQt5.QtCore import (Qt, QSize, QRectF)
    from PyQt5.QtWidgets import (QPushButton, QWidget, QVBoxLayout, QSpinBox, QLabel, 
                                 QComboBox, QHBoxLayout, QGraphicsScene, QGraphicsView, 
                                 QSlider, QGraphicsPixmapItem, QApplication, QGraphicsItem, 
                                 QListWidget, QListWidgetItem)
    from PyQt5.QtGui import (QColor, QBrush, QPixmap, QTransform, QPen, QPainterPath, QPainter, 
                             QPalette)
    # ------------------------------------------------------------------------------------
     
    import sys, os
     
    class GraphiqueScene(QGraphicsScene) :
     
        def __init__(self, parent = None) :
            super(GraphiqueScene, self).__init__(parent)
     
     
    class GraphiqueVue(QGraphicsView) :
     
        backgroundcolor = QColor(100, 100, 100)
     
        def __init__(self, parent = None) :
            super(GraphiqueVue, self).__init__(parent)
     
            self.setBackgroundBrush(self.backgroundcolor)
     
            self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing)
            self.setRenderHint(QPainter.TextAntialiasing)
            self.setDragMode(QGraphicsView.RubberBandDrag)
     
     
    class GraphiqueMain(QWidget):
        def __init__(self):
            super(GraphiqueMain, self).__init__()
     
            self.setWindowTitle("Demande d'aide pour multipage/multiscènes")
     
            self.setGeometry(20, 40, 1200, 760)
            self.setMinimumSize(1200, 760)
     
            # -------------------------------------------------------
            self.label_selection_page = QLabel("Sélection page :")
            self.label_selection_page.setEnabled(False)
            # -------------------------------------------------------
            bout_ajouter_page = QPushButton("Ajouter page")
            bout_ajouter_page.setFixedWidth(200)
            bout_supprimer_page = QPushButton("Supprimer page")
            bout_supprimer_page.setFixedWidth(200)
            bout_monter_page = QPushButton("▲")
            bout_monter_page.setMaximumWidth(50)
            bout_descendre_page = QPushButton("▼")
            bout_descendre_page.setMaximumWidth(50)
            bout_recommencer = QPushButton("Recommencer")
            bout_recommencer.setFixedWidth(170)
            bout_ajout_panneau = QPushButton("Ajouter panneau")
            bout_supp_panneau = QPushButton("Supprimer panneau")
            bout_taille_adaptee = QPushButton("Taille adaptée")
            # -------------------------------------------------------
            self.listwidget_pages = QListWidget()
            # Détection de la couleur du thème utilisé
            couleur_fenetre_theme = self.listwidget_pages.palette().color(QPalette.Window).name()
            # Le background du QListWidget se colore avec la couleur de la fenêtre du thème
            self.listwidget_pages.setStyleSheet("""QListWidget{background: %s;}""" % (couleur_fenetre_theme))
            #self.listwidget_pages.setSizeAdjustPolicy(self.listwidget_pages.AdjustToContents) ###################
            # -------------------------------------------------------       
            self.combo_pages = QComboBox()
            self.combo_pages.setMinimumHeight(28)
            self.combo_pages.setFixedWidth(150)
            self.combo_pages.setEnabled(False)
            # -------------------------------------------------------
            self.slider_redimensionnement = QSlider()
            self.slider_redimensionnement.setOrientation(Qt.Horizontal)
            self.slider_redimensionnement.setMinimum(100)
            self.slider_redimensionnement.setMaximum(3000)
            self.slider_redimensionnement.setValue(500)
            self.slider_redimensionnement.setSingleStep(1)
            self.slider_redimensionnement.setFixedWidth(150)
     
            hbox_widgets_boutons_graph = QHBoxLayout()
            hbox_widgets_boutons_graph.addWidget(bout_ajouter_page)
            hbox_widgets_boutons_graph.addWidget(bout_supprimer_page)
            hbox_widgets_boutons_graph.addWidget(bout_monter_page)
            hbox_widgets_boutons_graph.addWidget(bout_descendre_page)
            hbox_widgets_boutons_graph.addWidget(self.label_selection_page)
            hbox_widgets_boutons_graph.addWidget(self.combo_pages)
            hbox_widgets_boutons_graph.addWidget(bout_recommencer)
            # Alignement
            hbox_widgets_boutons_graph.setAlignment(Qt.AlignHCenter)
     
            hbox_listwidget = QHBoxLayout()
            hbox_listwidget.addWidget(self.listwidget_pages)
     
            vbox_layout_gauche = QVBoxLayout()
            vbox_layout_gauche.addLayout(hbox_widgets_boutons_graph)
            vbox_layout_gauche.addLayout(hbox_listwidget)
     
            #
            vbox_panneau_droite = QVBoxLayout()
            vbox_panneau_droite.addWidget(bout_ajout_panneau)
            vbox_panneau_droite.addWidget(bout_supp_panneau)
            vbox_panneau_droite.addWidget(QLabel("Redimensionner :"))
            vbox_panneau_droite.addWidget(self.slider_redimensionnement)
            vbox_panneau_droite.addWidget(bout_taille_adaptee)
            #
            vbox_panneau_droite.setAlignment(Qt.AlignVCenter)
     
            #
            hbox_layout = QHBoxLayout()
            hbox_layout.addLayout(vbox_layout_gauche)
            hbox_layout.addLayout(vbox_panneau_droite)
            #
            self.setLayout(hbox_layout)
     
            # ===============================================================================
            # Signaux
            # ===============================================================================
            bout_ajouter_page.clicked.connect(self.ajouter_page)
            bout_supprimer_page.clicked.connect(self.supprimer_page)
            bout_monter_page.clicked.connect(self.monter_page)
            bout_descendre_page.clicked.connect(self.descendre_page)
            bout_ajout_panneau.clicked.connect(self.ajouter_panneau)
            bout_supp_panneau.clicked.connect(self.supprimer_item)
            # Sélection d'une page
            self.combo_pages.currentIndexChanged.connect(self.selection_page)
            # Eliminer tout
            bout_recommencer.clicked.connect(self.recommencer)
            self.slider_redimensionnement.valueChanged.connect(self.redimensionner_selection)
            bout_taille_adaptee.clicked.connect(self.afficher_zoom_taille_adaptee)
     
            # -----------------------
            # Dictionnaire des scènes
            # -----------------------
            self.dico_scenes = {}
            # -----------------------
            # Dictionnaire des vues
            # -----------------------
            self.dico_vues = {}
            # -----------------------
            # Liste des scènes 
            # et des vues
            # -----------------------
            self.liste_scenes_vues = []
     
     
        ########################################################################
        def recalcul_resolution_scene(self) :
            # Hauteur par défaut de la fenêtre 
            # principale --> résolution 1200x760
            largeur_fenetre = self.frameSize().width()
            hauteur_fenetre = self.frameSize().height()
            if largeur_fenetre == 1200 : 
                hauteur_scene = 690
            else : 
                hauteur_scene = hauteur_fenetre - 100
            return hauteur_scene
        ########################################################################
     
     
        def selection_page(self) :
            index = self.combo_pages.currentIndex()
            # Sélection de la page (id du combo)
            # Affichage de la ligne de widget
            # concernée dans la QListWidget
            self.listwidget_pages.setCurrentRow(index)
            # Afficher la page en taille
            # adaptée. Appel fonction dédiée
            self.afficher_zoom_taille_adaptee()
     
     
        def nombre_elements(self) :
            # Récup du nbre d'éléments à la volée
            # (liste incrémentée avec la scène et la
            # vue pour chaque nouvelle page ajoutée)
            nbre_elem = len(self.liste_scenes_vues)
            return nbre_elem
     
     
        def ajouter_page(self) :
            # Récup du nbre d'éléments
            # à la volée (liste des
            # scènes et vues)
            n = self.nombre_elements()
     
            # Appel de la classes pour les scènes 
            # et les vues. Les données sont 
            # injectées dans des dictionnaires
            self.dico_scenes[n] = GraphiqueScene(self)
            self.dico_vues[n] = GraphiqueVue(self)
     
            # Mise en place des vues
            self.dico_vues[n] = GraphiqueVue(self.dico_scenes[n])
     
            # Ici mettre une image à charger (fond)
            self.affichage_vue('./page_blanche_portrait_150_dpi_1240x1754.png')
            # --------------------------------------------
     
            # Creation du widget principal
            widget = QWidget()
            #
            hbox_ligne_graph = QHBoxLayout()
            # Répartition dans la grille (avec le hbox)
            hbox_ligne_graph.addWidget(self.dico_vues[n])
            #
            widget.setLayout(hbox_ligne_graph)
            # Création d'un item du QListWidget
            itemGraph = QListWidgetItem()
            # Récupération de la valeur de la hauteur scène
            hauteur_scene = self.recalcul_resolution_scene() ###########
            # Faire en sorte que les lignes de widgets
            # soient bien fixées les unes au dessus des
            # autres et sans chevauchement
            itemGraph.setSizeHint(QSize(itemGraph.sizeHint().width(), hauteur_scene)) # hauteur_scene 690 par défaut
            # Ajout de l'item au QListWidget
            self.listwidget_pages.addItem(itemGraph)
            # Mise en place
            self.listwidget_pages.setItemWidget(itemGraph, widget)
            # La liste de widgets à l'id 0
            # est sélectionnée par défaut
            self.listwidget_pages.item(0).setSelected(True)
            # Afficher la page en taille
            # adaptée. Appel fonction dédiée
            self.afficher_zoom_taille_adaptee()
            # Incrémentation des sous listes [index, scene, vue] 
            # dans la liste des scènes et vues pour récupérer le
            # nombre de d'éléments (nbre de pages ... à la volée)
            self.liste_scenes_vues.append([n, self.dico_scenes[n], self.dico_vues[n]])
            #
            self.combo_pages.setEnabled(True)
            self.label_selection_page.setEnabled(True)
            # Ajout d'une page dans le combo à chaque
            # fois qu'une scène + vue est crée
            self.combo_pages.addItem("Page {}".format(self.combo_pages.count() + 1))
     
            # Affichage de la liste 
            # des scènes et vues
            print("# ---- ajouter_page ----")
            self.changements_graphs()
     
     
        def supprimer_page(self) :
            # Si aucune ligne de widgets n'a été 
            # sélectionnée par l'utilisateur ...
            if self.listwidget_pages.currentRow() == -1 :
                # ... c'est la dernière ligne 
                # de widgets qui est supprimée
                ligne_num_graph = self.listwidget_pages.count() - 1
            # Autrement c'est la ligne de widgets 
            # sélectionnée par l'utilisateur ...
            else :
                #  ... qui est supprimée
                # -------------------------------
                # Captation de la ligne de widgets
                # -------------------------------
                ligne_num_graph = self.listwidget_pages.currentRow()
     
            # Sélection de l'item (ligne de widgets)
            itemGraph = self.listwidget_pages.takeItem(ligne_num_graph)
     
            # Controle pour que index du row
            # ne soit pas négatif sur bouton 
            # supprimer (Out of range)
            if ligne_num_graph < 0 : return
     
            # Supression de la ligne de widgets
            self.listwidget_pages.removeItemWidget(itemGraph)
     
            # Suppression de la page sélectionnée dans le combo
            self.combo_pages.removeItem(ligne_num_graph)
     
            # Maj ... suppression de la scène et la 
            # vue à l'id concerné dans la liste des 
            # scènes et des vues
            del self.liste_scenes_vues[ligne_num_graph]
     
            # -----------------------------------------------------------------------
            # Suppression des éléments (scène et vue concernée) des dictionnaires
            # -----------------------------------------------------------------------
            del self.dico_scenes[ligne_num_graph]
            del self.dico_vues[ligne_num_graph]
            self.dico_scenes.update()
            self.dico_vues.update()
     
            # -----------------------------------------------------------------------
            # Nbre d'éléments dans les dictionnaires au 
            # moment de la suppression de la page
            # -----------------------------------------------------------------------
            nbre_elements_dico_scene = len(list(self.dico_scenes.keys()))
            nbre_elements_dico_vue = len(list(self.dico_vues.keys()))
     
            # -----------------------------------------------------------------------
            # Reconstitution des éléments du combo (pages)
            # -----------------------------------------------------------------------
            # La liste des éléments du 
            # combo est supprimée
            self.combo_pages.clear()
            # ... puis elle est recréé
            for nb in range(nbre_elements_dico_scene) :
                self.combo_pages.addItem("Page {}".format(nb + 1))
     
            # -----------------------------------------------------------------------
            # Appel de la fonction de réorganisation 2 des dictionnaires 
            # et des vuessuite à la suppression de la page
            # -----------------------------------------------------------------------
            self.reorganisation_2_scenes_vues()
     
            # Affichage de la liste 
            # des scènes et vues
            print("# ---- supprimer_page ----")
            self.changements_graphs()
     
     
        def reorganisation_1_scenes_vues(self) :
            ''' Fonction de réorganisation des dictionnaires pour les 
            scènes et vues suite à la descente ou montée des pages '''
     
            # Liste des index présents dans la liste des scènes et 
            # vues, par exemple ici dans la montée de la page 3 
            # (index 2) vers la page 2 (index 1) : [0, 2, 1, 3]
            liste_id_scenes_vues = [n[0] for n in self.liste_scenes_vues]
            # Mise en place d'une liste des scènes avec comme index
            # ceux crées dans la liste liste_id_scenes_vues
            l_scenes = [(elem[0], elem[1]) for elem in self.liste_scenes_vues]
            # Mise en place d'une liste des vues avec comme index
            # ceux crées dans la liste liste_id_scenes_vues
            l_vues = [(elem[0], elem[2]) for elem in self.liste_scenes_vues]
            # Création du dictionnaire des scènes
            # à partir de la liste l_scenes
            self.dico_scenes = dict(l_scenes)
            # Création du dictionnaire des vues
            # à partir de la liste l_vues
            self.dico_vues = dict(l_vues)
            self.dico_scenes.update()
            self.dico_vues.update()
     
     
        def reorganisation_2_scenes_vues(self) :
            ''' Fonction de réorganisation des dictionnaires pour les 
            scènes et vues, suite (par exemple) à la suppression, la 
            descente ou remontée d'une page. Particulièrement utile 
            lors de la suppression d'une page '''
     
            # -----------------------------------------------------------------------
            # Nbre d'éléments dans les dictionnaires au moment de 
            # la remontée, descente ou suppression de la page
            # -----------------------------------------------------------------------
            nbre_elements_dico_scene = len(list(self.dico_scenes.keys()))
            nbre_elements_dico_vue = len(list(self.dico_vues.keys()))
     
            # -----------------------------------------------------------------------
            # Recontitution des dictionnaires (et liste) des scènes et vues suite à la
            # suppression, montée ou descente d'une page --> pour que tout corresponde
            # -----------------------------------------------------------------------
            # On produit une liste avec les id (toutes 
            # les clés, par ex [0, 1, 2, 3], pour la scène)
            liste_id_cles_dico_scene = list(range(nbre_elements_dico_scene))
            # Liste des valeurs du dictionnaire pour la scène
            liste_valeurs_dico_scene = list(self.dico_scenes.values())
            # Un nouveau dictionnaire est crée (reconstitué) avec ces nouveaux éléments
            self.dico_scenes = dict(zip(liste_id_cles_dico_scene, liste_valeurs_dico_scene))
     
            # On produit une liste avec les id (toutes 
            # les clés, par ex [0, 1, 2, 3], pour la vue)
            liste_id_cles_dico_vue = list(range(nbre_elements_dico_vue))
            # Liste des valeurs du dictionnaire pour la vue
            liste_valeurs_dico_vue = list(self.dico_vues.values())
            # Un nouveau dictionnaire est crée (reconstitué) avec ces nouveaux éléments
            self.dico_vues = dict(zip(liste_id_cles_dico_vue, liste_valeurs_dico_vue))
     
            # La liste self.liste_scenes_vues est recrée avec les nouvelles données, par ex :
            # [[0, <__main__.GraphiqueScene object at 0x7fabaed8fdc8>, <__main__.GraphiqueVue object at 0x7fabaed8fee8>], 
            # [1, <__main__.GraphiqueScene object at 0x7fab99f555e8>, <__main__.GraphiqueVue object at 0x7fab99f55708>], 
            # [2, <__main__.GraphiqueScene object at 0x7fab99f559d8>, <__main__.GraphiqueVue object at 0x7fab99f55af8>]]
            self.liste_scenes_vues = [[parc1, parc2[1], parc2[2]] for parc1, parc2 in enumerate(self.liste_scenes_vues)]
            # -----------------------------------------------------------------------
     
     
        def monter_page(self) :
            # Captation du numéro de la ligne de widgets  
            # sélectionnée par l'utilisateur (1, 2, 3, ...)
            ligne_num_graph = self.listwidget_pages.currentRow()
            # Si le nombre de lignes de widgets est 
            # supérieur à 0 ... les choses peuvent se faire
            if ligne_num_graph > 0 :            
                ligne_graph = self.listwidget_pages.itemWidget(self.listwidget_pages.currentItem())
                itemGraph = self.listwidget_pages.currentItem().clone()
     
                self.listwidget_pages.insertItem(ligne_num_graph - 1, itemGraph)
                self.listwidget_pages.setItemWidget(itemGraph, ligne_graph)
     
                self.listwidget_pages.takeItem(ligne_num_graph + 1)
                self.listwidget_pages.setCurrentRow(ligne_num_graph - 1)
     
            # Numéro réel (index) de la ligne de widgets (0, 1, 2, ....)
            id_ligne_graph = ligne_num_graph - 1
     
            # Controle que index du row ne soit pas négatif sur bouton monter(Out of range)
            if id_ligne_graph < 0:
                return
     
            # Echange des index (permutation des données) pour que les valeurs soient placées au bon endroit (en  
            # corrélation complète avec le placement des lignes de widgets ... telles que celles que l'on voit à l'écran)
            self.liste_scenes_vues[id_ligne_graph], self.liste_scenes_vues[ligne_num_graph] = self.liste_scenes_vues[ligne_num_graph], self.liste_scenes_vues[id_ligne_graph]
     
            # Appel de la fonction de réorganisation 
            # 1 des dictionnaires et des vues
            self.reorganisation_1_scenes_vues()
            # Appel de la fonction de réorganisation 
            # 2 des dictionnaires et des vues
            self.reorganisation_2_scenes_vues()
     
            # Affichage de la liste 
            # des scènes et vues
            print("# ---- monter_page ----")
            self.changements_graphs()
     
     
        def descendre_page(self) :
            # Captation du numéro de la ligne de widgets  
            # sélectionnée par l'utilisateur (1, 2, 3, ...)
            ligne_num_graph = self.listwidget_pages.currentRow()
            # Pas de ligne sélectionnée ... abandon
            if ligne_num_graph == -1 : return
            # Autrement si une ligne est sélectionnée ...
            elif ligne_num_graph < self.listwidget_pages.count():
                ligne_graph = self.listwidget_pages.itemWidget(self.listwidget_pages.currentItem())
                itemGraph = self.listwidget_pages.currentItem().clone()
     
                self.listwidget_pages.insertItem(ligne_num_graph + 2, itemGraph)
                self.listwidget_pages.setItemWidget(itemGraph, ligne_graph)
     
                self.listwidget_pages.takeItem(ligne_num_graph)
                self.listwidget_pages.setCurrentRow(ligne_num_graph + 1)
     
            # Numéro réel (index) de la ligne de widgets (0, 1, 2, ....)
            id_ligne_graph = ligne_num_graph + 1
     
            # -------------------------------
            # Echange des index (donc des data) pour que les valeurs soient placées au bon endroit (en corrélation 
            # complète avec le placement des lignes de widgets ... telles que celles que l'on voit à l'écran)
            # -------------------------------
            # Ne produit pas d'erreur si on essaie de descendre la 
            # la ligne de widget plus bas que la dernière ligne
            # ligne (c'est à dire qu'on arrête pas de cliquer sur 
            # le bouton pour descendre)
            if self.listwidget_pages.count() >= ligne_num_graph + 2 :
                # Echange ...
                self.liste_scenes_vues[ligne_num_graph], self.liste_scenes_vues[id_ligne_graph] = self.liste_scenes_vues[id_ligne_graph], self.liste_scenes_vues[ligne_num_graph]
     
            # Appel de la fonction de réorganisation 
            # 1 des dictionnaires et des vues
            self.reorganisation_1_scenes_vues()
            # Appel de la fonction de réorganisation 
            # 2 des dictionnaires et des vues
            self.reorganisation_2_scenes_vues()
     
            # Affichage de la liste 
            # des scènes et vues
            print("# ---- descendre_page ----")
            self.changements_graphs()
     
     
        def recommencer(self) :
            self.listwidget_pages.clear()
            self.combo_pages.clear()
            self.dico_scenes.clear()
            self.dico_vues.clear()
            # Le label le combo sont dégrisés
            self.label_selection_page.setEnabled(False)
            self.combo_pages.setEnabled(False)
            self.liste_scenes_vues.clear()
            # Affichage de la liste 
            # des scènes et vues
            print("# ---- recommencer ----")
            self.changements_graphs()
     
     
        def affichage_vue(self, image) :
            # Récup du nbre d'éléments
            # à la volée (liste des
            # scènes et vues)
            n = self.nombre_elements()
            pixmap = QPixmap(image)
            item = QGraphicsPixmapItem(pixmap)
            item.setTransformationMode(Qt.SmoothTransformation)
            self.dico_scenes[n].addItem(item)
            self.dico_vues[n].setScene(self.dico_scenes[n])
            x, y = 0, 0
            self.dico_scenes[n].setSceneRect(0, 0, pixmap.width(), pixmap.height())
            self.dico_vues[n].centerOn(x, y)
            self.dico_vues[n].setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
            self.dico_vues[n].fitInView(self.dico_scenes[n].sceneRect(), Qt.KeepAspectRatio)
            self.dico_vues[n].update()
     
     
        def changements_graphs(self) :
            print("Scènes et vues :", self.liste_scenes_vues)
     
     
        def ajouter_panneau(self) :
            contour = QPen(QColor(0, 0, 0, 255), 15)
            contour.setStyle(Qt.DotLine)
            contour.setCapStyle(Qt.RoundCap)
            contour.setJoinStyle(Qt.RoundJoin)
            chemin = QPainterPath()
            chemin.addRoundedRect(QRectF(10, 10, 740, 200), 30, 30)
            # Récup du nbre d'éléments
            # à la volée (liste des
            # scènes et vues)
            nbre_elems = self.nombre_elements()
            # 1ère page
            if nbre_elems == 1 :
                # self.dico_scenes[0] représente la scène dès que la 1ère page est ajoutée
                rectangle = self.dico_scenes[0].addPath(chemin, pen = contour, brush = QBrush(QColor(120, 136, 145, 160)))
            # Pages suivantes ...
            elif nbre_elems > 1 :
                rectangle = self.dico_scenes[self.combo_pages.currentIndex()].addPath(chemin, pen = contour, brush = QBrush(QColor(120, 136, 145, 160)))
            # ---------------------------------------------------------
            rectangle.setFlag(QGraphicsItem.ItemIsMovable)
            rectangle.setFlag(QGraphicsItem.ItemIsSelectable)
     
     
        def supprimer_item(self) :
            nbre_elems = self.nombre_elements()
            # 1ère page
            if nbre_elems == 1 :
                for item in self.dico_scenes[0].selectedItems() :
                    self.dico_scenes[0].removeItem(item)
                    del item
            # Pages suivantes ...
            elif nbre_elems > 1 :
                for item in self.dico_scenes[self.combo_pages.currentIndex()].selectedItems() :
                    self.dico_scenes[self.combo_pages.currentIndex()].removeItem(item)
                    del item
     
     
        def redimensionner_selection(self, valeur) :
            nbre_elems = self.nombre_elements()
            # 1ère page
            if nbre_elems == 1 :
                for item in self.dico_scenes[0].selectedItems() :
                    transform = QTransform()
                    transform.scale(valeur/1000, valeur/1000)
                    item.setTransform(transform)
                    self.update()
            # Pages suivantes ...
            elif nbre_elems > 1 :
                for item in self.dico_scenes[self.combo_pages.currentIndex()].selectedItems() :
                    transform = QTransform()
                    transform.scale(valeur/1000, valeur/1000)
                    item.setTransform(transform)
                    self.update()
     
     
        def afficher_zoom_taille_adaptee(self) :
            nbre_elems = self.nombre_elements()
            try :
                # 1ère page
                if nbre_elems == 1 :
                    self.dico_vues[0].setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
                    self.dico_vues[0].fitInView(self.dico_scenes[0].sceneRect(), Qt.KeepAspectRatio)
                # Pages suivantes ...
                elif nbre_elems > 1 :
                    self.dico_vues[self.combo_pages.currentIndex()].setAlignment(Qt.Alignment(Qt.AlignHCenter|Qt.AlignVCenter))
                    self.dico_vues[self.combo_pages.currentIndex()].fitInView(self.dico_scenes[self.combo_pages.currentIndex()].sceneRect(), Qt.KeepAspectRatio)
            except : pass
     
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = GraphiqueMain()
        ex.show()
        sys.exit(app.exec_())
    A bientôt.

Discussions similaires

  1. XMLCode documentation et multi space name
    Par hbailliet dans le forum C#
    Réponses: 3
    Dernier message: 19/07/2017, 20h02
  2. [WD-2010] Modele document word multi-utilisateurs
    Par gueulederack dans le forum Word
    Réponses: 1
    Dernier message: 23/12/2013, 11h06
  3. [2D/3D] OpenGL : 1 scène, 2 vues
    Par bobyboby dans le forum Qt
    Réponses: 0
    Dernier message: 08/03/2010, 03h14
  4. scanner un document multipage depuis vb.net
    Par monmiez dans le forum Windows Forms
    Réponses: 4
    Dernier message: 09/02/2009, 09h34
  5. [WinDev 9] Scan d'un document multipage vers PDF
    Par litdwarf dans le forum WinDev
    Réponses: 2
    Dernier message: 13/10/2006, 13h00

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