Merci encore pour l'aide, j'avais oublié que le property ne marcherai pas dans la méthode __init__.:ccool:
Enfin malheureusement le trait ne reste pas, j'ai l'impression qu'il ne reste pas dans la vue :s
Version imprimable
Merci encore pour l'aide, j'avais oublié que le property ne marcherai pas dans la méthode __init__.:ccool:
Enfin malheureusement le trait ne reste pas, j'ai l'impression qu'il ne reste pas dans la vue :s
Chez moi, le code que j'ai envoyé laisse un trait lorsque j'utilise le bouton gauche de la souris pour le tracer (avec le droit il me fait un truc étrange)
Oui, c'est normal j'ai mis une condition pour que cela soit uniquement le gauche
l.157 leftButton
pour vérifier qu'on clique bien à gauche.
Malgré tout, le trait disparait, c'est étonnant :s.
C'est plutôt étrange que ça ne marche pas chez toi.
Mon setup:
Code:
1
2
3
4
5 - Windows 7 (x64) - Python 2.7 (x64) - PySide 1.1.0 final 1 (x64) - Qt 4.7.4 (x64)
J'ai exactement la même config en plus lol
Je viens de réessayer, même en enregistrant les lignes apparaissent. Quel comportement as-tu exactement ?
Je pense que cela n'a pas d'importance car je vais étudier comment dessiner avec un arc (cercle ) et puis avoir la même couleur que celle que je veux pour pouvoir gommer.
En faites, à chaque fois que je trace un nouveau trait l'ancien disparait .
Si je clique sur mon bouton rubber enfin si je le décoche, le trait reste et quand je reclique il disparait.
Je pense qu'il ne faut pas rester sur un échec mais bon.
Pour l'arc de cercle (pour faire un cercle complet), la documentation devrait amplement suffire (au pire il y a toujours celle de Qt4 directement).
EDIT: les traits restent même en jouant avec la case à cocher :(
Je suis d'accord, cela m'énerve aussi.
Malgré tout, l'objectif finale pour moi est la gomme, le trait c'était juste pour l'entrainement.
Je vais étudier encore la doc, la difficulté sera de sélectionner la couleur que je veux, j'imagine.
Merci encore,bonne soirée.:ccool:
EDIT :
Voici l'erreur que j'ai en console
QPainter::begin: Paint device returned engine == 0, type: 3
En faite, me revoici, j'ai réussi à dessiner mon cercle malgré tout il ne reste pas afficher :(.
Et je me demande si il faudrait pas mieux une freeHandline pour pouvoir balader ma gomme où je veux à méditer ^^.
Code:
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 class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.image = ImageView(QImage()) self.resize(500, 300) self.setWindowTitle("Image loader") statusbar = QStatusBar(self) self.setStatusBar(statusbar) """ Adding of actions for the tool bar """ iconToolBar = self.addToolBar("iconBar") #About _actionAbout = QAction(self) _actionAbout.triggered.connect(self._actionAbout) _actionAbout.setIcon(QIcon("Pics\info-icon.jpg")) _actionAbout.setStatusTip("Pop up the About dialog.") iconToolBar.addAction(_actionAbout) #Rubber _actionRubber = QAction(self) _actionRubber.setIcon(QIcon("Pics\eraser2.png")) _actionRubber.setStatusTip("Enable or Disable eraser tool") iconToolBar.addAction(_actionRubber) """ Add of scroll bars to see properly the images """ self.area = QScrollArea(self) self.area.setWidget(self.image) self.area.setWidgetResizable(True) self.setCentralWidget(self.area) """ Add of the Menu which contains all the features like of Open/Save/.. and the edit options """ menu = QMenuBar() self.setMenuBar(menu) _file = menu.addMenu('File') _edit = menu.addMenu("Edit") # Menu Open _action = QAction('Open', _file,shortcut=QKeySequence.Open) _action.triggered.connect(self.__actionOpen) _file.addAction(_action) # Menu Save _action = QAction('Save', _file,shortcut=QKeySequence.Save) _action.triggered.connect(self.__actionSave) _file.addAction(_action) # Menu Close _action = QAction('Close', _file,shortcut=QKeySequence.Close) _action.triggered.connect(self.__actionClose) _file.addAction(_action) #Menu Edit #Check Box rub self._ckbox = QCheckBox("Rubber On") statusbar.addWidget(self._ckbox) if self._ckbox.isChecked(): self._mode = "rub" else : self._mode = "select" #Init of the boolean to know whether we select or rub self.image.mode = self._mode self._ckbox.stateChanged.connect(self.__rubberBoxChanged) def __rubberBoxChanged(self, state): if self._ckbox.isChecked(): self._mode = 'rub' else: self._mode = 'select' self.image.mode = self._mode def __actionOpen(self): _file = QFileDialog.getOpenFileName(self, "Open Image", "", "Image Files (*.png *.jpg *.bmp)") if _file: self.image.setWorkingImage(QImage(_file[0])) else: print "Invalid Image" def __actionSave(self): _file = QFileDialog.getSaveFileName(parent=None, caption="Save image as") _result = self.image.workingImage().save(_file[0], "BMP", -1) # Test to know if it's working if _result: print "Saved successfully" else : print "Saving failed" def __actionClose(self): self.close() def _actionAbout(self): '''Popup a box with about message.''' QMessageBox.about(self, "About PySide, Platform and the like", """<b> About this program </b> <p>Copyright 2012 Maugin Guillaume. All rights reserved in accordance with GPL v2 or later <p>This application can be used for displaying OS and platform details. <p>Python %s - PySide version %s - Qt version %s on %s""" ) class ImageView(QWidget): def __init__(self, image, parent=None): super(ImageView, self).__init__(parent=parent) self.__image = image self._mode ="rub" #self._getMode() #Get of the mode self._mode = image.mode #Init of selection self.__band = QRubberBand(QRubberBand.Rectangle, self) self.__origin = None #Init of rubber #the rub is a rectangle that should be the size of one pixel and the color and full # of the one selected def getMode(self): return self._mode def setMode(self,_newMode): self._mode= _newMode self.update() def setWorkingImage(self, img): self.__image = img self.setMinimumSize(img.size()) self.update() def workingImage(self): return self.__image def mousePressEvent(self, e): self.__origin = e.pos() if self._mode =="select": #__ private variable self.__band.setGeometry(QRect(self.__origin, QSize())) self.__band.show() if self._mode =="rub": if e.button() == Qt.LeftButton : self.x1 = e.x() self.y1 = e.y() def mouseReleaseEvent(self, e): self.__band.hide() if self._mode =="select": print "La selection est :", QRect.intersect(self.__band.geometry(), self.rect()) if self._mode =="rub": if e.button() == Qt.LeftButton : self.x2 = e.x() self.y2 = e.y() painter = QPainter(self.__image) #painter.drawLine(self.x1,self.y1,self.x2,self.y2) painter.drawArc(self.x1, self.y1,2,3,5760,5760) self.update() def mouseMoveEvent(self, e): self.__band.setGeometry(QRect(self.__origin, e.pos()).normalized()) if self._mode == "rub": self.x2 = e.x() self.y2 = e.y() self.update() def paintEvent(self, e): painter = QPainter(self) painter.drawImage(self.rect(), self.__image) #Drawin of the rub try: painter.drawArc(self.x1, self.y1,20,30,5760,5760) #painter.drawLine(self.x1,self.y1,self.x2,self.y2) except: pass #Init of the property for mode mode = property(getMode, setMode) if __name__ == '__main__': app = QApplication([]) win = MainWindow() win.show() app.exec_()
Dans paintEvent et mouseReleaseEvent remplacer le drawArc par ceci
en respectant l'indentation d'origine bien sur.Code:
1
2
3
4 w = abs(self.x2 - self.x1) h = abs(self.y2 - self.y1) painter.drawArc(self.x1, self.y1, w, h,5760,5760)
Voici des exemples de ce que j'ai déjà réalisé, ce que j'aimerais pouvoir faire et à peu près similaire en effet j'aimerais avoir une ligne qui se déplace ou un cercle sinon et qui est "drag" pour pouvoir gommer .
J'espère cela pourra aider pour la suite^^.:lol:
Freehand line, déplaçable à la main
Code:
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 public class FreehandLineTool extends Tool{ private FreehandLine freehand; public FreehandLineTool(ViewPanel viewPanel){ super(viewPanel); } public void mouseDragged(MouseEvent event){ if(freehand == null) { freehand = new FreehandLine(this.getStart().getX(),this.getStart().getY()); } /* freehand c'est mon tableau de point , j'ajoute un segment pour chaque point */ Point point = event.getPoint(); freehand.addSegment(point.getX(),point.getY()); } public void mouseReleased(MouseEvent event){ System.out.println("Event "+ event); System.out.println("Freehand " + freehand); if(freehand != null){ freehand.addSegment(event.getPoint().getX(),event.getPoint().getY()); super.mouseReleased(event); freehand = null; } } protected View createView(){ freehand.setLineColour(this.getViewPanel().getCurrentDrawColour()); View viewligne = new View(freehand); return viewligne; } }
Rubber tool implémentant la gomme donc
EDIT : pour l'erreur d'affichage, j'ai trouvé ma réponse enfin je croisCode:
1
2
3
4
5
6
7
8
9
10
11
12
13 public class RubberTool { Stroke currentStroke= new BasicStroke(20); public RubberTool(BeAnArtistFrame myFrame){ FreehandLine freehand = new FreehandLine(0,0); freehand.setCurrentStroke(currentStroke); freehand.setLineColour(Color.white); new View(freehand); } }
"Tu peux dessiner sur une image (QPixmap, QImage, QPicture, ...), mais pas sur un widget, en dehors de la fonction QWidget::paintEvent.
Essaye plutôt QGraphicsScene/QGraphicsView "
J'essayai de dessiner sur le widget malgré tout je pense qu'il faudrait peut être que j'utilise scene et view car j'ai quand un comportement étrange après plusieurs dessins, les ronds se font n'importe où.
Pour effacer avec un cercle, drawPie au lieu de drawArc permet d'avoir un cercle plein avec la couleur de son choix.
Le 'free hand tool', avec drawPath je pense.
Si tu veux beaucoup de 'tools' différents, il serait judicieux de revoir l'architecture du code. En effet, si ton projet est voué à se complexifier, il vaut mieux prévoir le coup en créant une spécification technique (rien de trop compliqué) puis faire un diagramme de classes type UML. Cela permet entre autres de résoudre les problèmes logiques et structurels avant de toucher une seule ligne de code et de s'embourber dans des tonnes de patchs, hacks et j'en passe.
Lorsqu'une difficulté technique survient, faire un bout de code de test hors contexte afin de valider le fonctionnement, puis l'intégrer proprement d'abord dans le modèle UML et ensuite dans le code.
L'exemple de logique que j'ai donné précédemment pour l'ImageView fait partie de cette réflexion.
Enfin, kolourpaint http://kolourpaint.org/download.html est certes une application KDE mais je pense que son code source pourrait t'aider à mieux comprendre comment fonctionne ce genre de logiciels (flow de l'application, méthodologie, etc).
Si tu as des questions, n'hésite pas.
EDIT pour l'edit de ton post précédent: Ce qui est étrange c'est que le code que j'ai modifié puis posté fonctionne correctement chez moi, et le dessin est effectué dans le paintEvent en ce qui concerne le widget.
Bien évidemment, mon application est vouée à ce complexifier et je ne passerais pas à coté de l'étape de spécification qui est fondamentale.
Je voulais voir si cela valait le coup de continuer sur cette voie et je commence à mieux comprendre le Python donc je vais m'accrocher.
Je vais commencer à créer mon UML pour mieux appréhender le futur ^^.
Bonne chance dans ce cas, et n'oublie pas de vérifier l'orthographe de tes posts (c'est toujours plus agréable à lire).
Ci-joint, mon premier diagramme à voir si cela est cohérent avec ce qui te semble juste.
Étant débutant surtout en python, j'ai du mal à faire le lien entre l'UML et ce langage.
PS : parfois, j'écris trop vite, ceci explique les fautes, je veillerai à faire attention à ses fautes :)
Je n'ai pas trop compris à quoi la QGraphicsScene sert, par contre avant de faire ton UML il serait utile de lister les spécifications de ton application (que doit-elle être capable de faire, comment doit-elle réagir dans ce cas ci ou celui-la, voir même faire une maquette des différentes actions et écrans).
PS: pour faire des maquettes de manière informatique tu as par exemple Balsamiq http://builds.balsamiq.com/b/mockups-web-demo/. Sinon une feuille et un crayon papier font aussi bien l'affaire.
Je vais m'y mettre aussi sérieusement.
Le graphicScene permettra d'ajouter les éléments graphiques et puis à l'intérieur de la view, il y aura l'image , la gomme, etc...
Je comprend mieux ce que tu as en tête, pense simplement que les évènements souris/clavier devront être gérés par la QGraphicsScene et non l'ImageView.