Bonjour,
Je réalise une petite interface pour visualiser facilement l'organisation de tâches en face de ressources (des opérateurs). Je n'ai pas trouvé mon bonheur dans les graphiques proposés par la bibliothèque Qt, j'ai donc commencé à programmé une interface avec d'un côté ma liste de ressource (un QListeView), et d'un autre côté une zone graphique avec QGraphicsView --> QGraphicScene.
Version Python: 3.8.2
Version PyQt: 5.14
Mon souci est de garder l'alignement entre les lignes du tableau et les graphiques.
Pour le moment je récupérer la ligne du tableau avant de créer la représentation des tâches et calcul le point Y. Mais les rectangles que je dessine sont toujours alignés en haut à gauche.
En cherchant ici: https://vincent-vande-vyvre.developp...lation-images/ et également dans la doc de Qt, j'ai vu que l'on pouvait inclure des Widget dans une scène. Du coup, je me demande quelle est l'approche la plus facile, la plus lisible et la plus évolutive si demain la liste doit être scrollable.
Je ne veut pas gérer cette liste comme les autre objet graphique: elle doit rester à gauche de l'écran et être toujours visible, même si l'utilisateur Zoom dans la scène et se déplace à gauche ou à droite.
Après cette étape, je compte rajouter une règle qui restera en haut du Graphique View pour donner l'échelle de temps. Donc la haussi, un groupe de graphique qui ne devra pas bouger verticalement si on scroll vers le bas.
Code de l'interface (créée avec Designer et pyuic):
Code pour la création de la représentation des tâches:
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 def setupUi(self, CtrlTmp_Desktop): CtrlTmp_Desktop.setObjectName("CtrlTmp_Desktop") CtrlTmp_Desktop.resize(728, 568) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(CtrlTmp_Desktop.sizePolicy().hasHeightForWidth()) CtrlTmp_Desktop.setSizePolicy(sizePolicy) CtrlTmp_Desktop.setMinimumSize(QtCore.QSize(200, 0)) CtrlTmp_Desktop.setMaximumSize(QtCore.QSize(1677721, 16777215)) self.centralwidget = QtWidgets.QWidget(CtrlTmp_Desktop) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_3.setObjectName("verticalLayout_3") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.Jm1 = QtWidgets.QPushButton(self.centralwidget) self.Jm1.setObjectName("Jm1") self.horizontalLayout.addWidget(self.Jm1) self.dateEdit = QtWidgets.QDateEdit(self.centralwidget) self.dateEdit.setObjectName("dateEdit") self.horizontalLayout.addWidget(self.dateEdit) self.Jp1 = QtWidgets.QPushButton(self.centralwidget) self.Jp1.setToolTipDuration(-1) self.Jp1.setObjectName("Jp1") self.horizontalLayout.addWidget(self.Jp1) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) self.verticalLayout_3.addLayout(self.horizontalLayout) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.verticalLayout_2 = QtWidgets.QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.label = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth()) self.label.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setPointSize(14) font.setBold(False) font.setWeight(50) self.label.setFont(font) self.label.setObjectName("label") self.verticalLayout_2.addWidget(self.label) self.listView = QtWidgets.QListView(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.listView.sizePolicy().hasHeightForWidth()) self.listView.setSizePolicy(sizePolicy) self.listView.setObjectName("listView") self.verticalLayout_2.addWidget(self.listView) self.horizontalLayout_3.addLayout(self.verticalLayout_2) self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalSlider = QtWidgets.QSlider(self.centralwidget) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") self.verticalLayout.addWidget(self.horizontalSlider) self.graphicsView = QtWidgets.QGraphicsView(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth()) self.graphicsView.setSizePolicy(sizePolicy) self.graphicsView.setToolTip("") self.graphicsView.setFrameShape(QtWidgets.QFrame.HLine) self.graphicsView.setMidLineWidth(1) self.graphicsView.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) self.graphicsView.setObjectName("graphicsView") self.verticalLayout.addWidget(self.graphicsView) self.horizontalScrollBar = QtWidgets.QScrollBar(self.centralwidget) self.horizontalScrollBar.setOrientation(QtCore.Qt.Horizontal) self.horizontalScrollBar.setObjectName("horizontalScrollBar") self.verticalLayout.addWidget(self.horizontalScrollBar) self.horizontalLayout_3.addLayout(self.verticalLayout) self.verticalLayout_3.addLayout(self.horizontalLayout_3) CtrlTmp_Desktop.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(CtrlTmp_Desktop) self.menubar.setGeometry(QtCore.QRect(0, 0, 728, 21)) self.menubar.setObjectName("menubar") self.menuMenu = QtWidgets.QMenu(self.menubar) self.menuMenu.setObjectName("menuMenu") self.menuConfigurer = QtWidgets.QMenu(self.menuMenu) self.menuConfigurer.setObjectName("menuConfigurer") CtrlTmp_Desktop.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(CtrlTmp_Desktop) self.statusbar.setObjectName("statusbar") CtrlTmp_Desktop.setStatusBar(self.statusbar) self.actionQuitter = QtWidgets.QAction(CtrlTmp_Desktop) self.actionQuitter.setObjectName("actionQuitter") self.actionMon_Equipe = QtWidgets.QAction(CtrlTmp_Desktop) self.actionMon_Equipe.setObjectName("actionMon_Equipe") self.actionMon_Atelier = QtWidgets.QAction(CtrlTmp_Desktop) self.actionMon_Atelier.setObjectName("actionMon_Atelier") self.menuConfigurer.addAction(self.actionMon_Equipe) self.menuConfigurer.addAction(self.actionMon_Atelier) self.menuMenu.addAction(self.actionQuitter) self.menuMenu.addAction(self.menuConfigurer.menuAction()) self.menubar.addAction(self.menuMenu.menuAction()) self.retranslateUi(CtrlTmp_Desktop) self.actionQuitter.triggered.connect(CtrlTmp_Desktop.close) QtCore.QMetaObject.connectSlotsByName(CtrlTmp_Desktop)
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 class RepSequence(): def __init__(self,ID_eventDebut,Sequence,ID_User,dtDebut=QDateTime(),ID_eventFin=0,dtFin=QDateTime.currentDateTime(),multi=0,codeFin=None): #Dans un seul objet, assemblage des données qui définissent une période de travail: # - Evenement de début (code événement toujours 0, donc non conservé) avec: # ID de l'événement (clé primaire de la table # DT de début # - Evenement de fin (non renseigné si action en cours==> valeur par défaut) # DT de fin (défaut DT actuel = en cours) # ID de l'événément # codeFin: type d'arrêt de séquence réalisé par l'opérateur (None si en cours) # - Sequences: liste des séquecnes concernées # - Multi: code de regroupement si plusieurs séquence #Definition des données internes, avec vérification existance pour la fin self.ID_eventDebut = ID_eventDebut self.Sequences = [Sequence] self.ID_User = ID_User + 2 #Commence à 0, en haut à gauche self.multi = multi self.globalModified = False #Défini le jour d'exécution au jour de début tpdt = QDateTime.fromString(dtDebut,"yyyy-MM-dd HH:mm:ss'.0'") self.jourTravail = tpdt.date() self.heureDebut = tpdt.time() self.debutModified = False if isinstance(dtFin,str): tpdt = QDateTime.fromString(dtDebut,"yyyy-MM-dd HH:mm:ss'.0'") else: tpdt = dtFin #Verifie que le jour de fin est bien égale au jour de début. if tpdt.date() == self.jourTravail: self.heureFin = tpdt.time() self.ID_eventFin = ID_eventFin self.codeFin = codeFin else: #Récupére l'heure de fin d'équipe suivant le jour considéré self.heureFin = LocalCal.heureFinEquipe(self.jourTravail) self.ID_eventFin = 0 self.codeFin = 3 self.finModified = False def show(self): #Defini le rectangle représantant l'opération # x = heure de début en minutes x = self.heureDebut.minute()+self.heureDebut.hour()*60 # y = aligné sur l'utilisateur, ID * h y = self.ID_User * 12 # w = durée en minutes w = self.heureFin.minute()+self.heureFin.hour()*60-x self.rectSeq = QGraphicsRectItem(x, y, w, 12) #Paramétre le contour et intérieur suivant le code de fin if self.codeFin == None: pen = QPen(Qt.black,2,Qt.DashLine,Qt.SquareCap,Qt.BevelJoin) brush = QBrush(Qt.lightGray,Qt.RadialGradientPattern) elif self.codeFin == 3: pen = QPen(Qt.black,2,Qt.SolidLine,Qt.SquareCap,Qt.BevelJoin) brush = QBrush(Qt.blue,Qt.RadialGradientPattern) elif self.codeFin == 10: pen = QPen(Qt.black,3,Qt.SolidLine,Qt.SquareCap,Qt.BevelJoin) brush = QBrush(Qt.green,Qt.SolidPattern) else: pen = QPen(Qt.black,2,Qt.SolidLine,Qt.SquareCap,Qt.BevelJoin) brush = QBrush(Qt.blue,Qt.Dense2Pattern) self.rectSeq.setPen(pen) self.rectSeq.setBrush(brush) #Défini le tooltype: heure de début et de fin, et liste des séquences #TODO: utiliser les infos de D-OF: PF, désignation, poste de travail liste_seq = '' for txt in self.Sequences : liste_seq = liste_seq + "\n %s"%txt text = """Utilisateur %s - ligne %s \nDe %s à %s \n %s""" %(self.ID_User,y,self.heureDebut.toString(),self.heureFin.toString(), liste_seq) self.rectSeq.setToolTip(text) #Renvoi l'objet graphique return self.rectSeq
Partager