Une méthode qui ne veut obéir qu'à une partie des boutons et pas aux autres!
Herve
Membre
Problème résolu, merci pour votre aide
Bonjour à tous,
Quel est ce tour de magie???
J'ai deux séries de boutons créés (grâce à l'aide de membres de ce forum d'ailleurs) par code, une méthode de calculs (dans l'App controller) dont les résultats modifient la couleur de la seconde série de boutons. Tout va bien jusque là :
série de boutons 1 > méthode (void) de calculs > série de boutons 2. Très bien, tout va bien.
Cette méthode de calculs est appelée aussi par une autre série de boutons plus généraux que j'ai créé avec Interface Bulder>IIBOutlet dans l'App Controller;
boutons IB > méthode de calculs : très bien, les calculs sont bien réalisés.
mais méthode de calcul > série de boutons 2 : le message n'arrive pas!!!!!
Le message consiste en une série de set(float) (faits avec property/synthesize) et une méthode :
(le texte du NSLog n'apparaà®t pas non plus dans la console.)
Est-ce le moment d'employer des "NSNotifications", des "Key observer" et autres nouveautés dans Cocoa par rapport à Java? J'ai passé la journée à essayer de comprendre. Les boutons de la première série agissent très bien sur la méthode pourtant!!!
Quelqu'un ici aurait une idée de ce que cette chose peut être?
Bonjour à tous,
Quel est ce tour de magie???
J'ai deux séries de boutons créés (grâce à l'aide de membres de ce forum d'ailleurs) par code, une méthode de calculs (dans l'App controller) dont les résultats modifient la couleur de la seconde série de boutons. Tout va bien jusque là :
série de boutons 1 > méthode (void) de calculs > série de boutons 2. Très bien, tout va bien.
Cette méthode de calculs est appelée aussi par une autre série de boutons plus généraux que j'ai créé avec Interface Bulder>IIBOutlet dans l'App Controller;
boutons IB > méthode de calculs : très bien, les calculs sont bien réalisés.
mais méthode de calcul > série de boutons 2 : le message n'arrive pas!!!!!
Le message consiste en une série de set(float) (faits avec property/synthesize) et une méthode :
- (void) redessine{<br /> NSLog(@"appel redessine palette");<br /> [self setNeedsDisplay:YES];<br />}<br />
(le texte du NSLog n'apparaà®t pas non plus dans la console.)
Est-ce le moment d'employer des "NSNotifications", des "Key observer" et autres nouveautés dans Cocoa par rapport à Java? J'ai passé la journée à essayer de comprendre. Les boutons de la première série agissent très bien sur la méthode pourtant!!!
Quelqu'un ici aurait une idée de ce que cette chose peut être?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
NSlog absent => méthode pas appelée.
Méthode appelée par le couple Target/Action
Vérifier que les boutons ont bien leur target fixée sur l'objet qui contient la méthode (et que l'objet n'est pas "nil" au runtime).
Si la cible est bien là regarder si l'Action est la bonne.
PS: quand on les crée dans IB Action a toujours un paramètre: (id)sender et donc @selector(uneMethode uneMethode doit avoir ses deux points : qui signalent un argument à venir. IB t'y oblige, c'est à ce genre de détails qu'on l'apprécie...
Je suis un peu surpris de voir que tes autres boutons font fonctionner la méthode redessine sans argument d'ailleurs...
J'attendrais plutôt une méthode
Les deux méthodes à l'évoute des boutons ont bien un (id sender ou pour l'autre un (NSButton*) sender.
Les boutons qui marchent ont :
Les IBAction qui ne marchent qu'à moitié ont :
En fin de calculeValeurs, il y a :
C'est cela qui ne marche qu'avec les premiers boutons.
J'ai fait comme en Java, appelé une méthode de classe (déclarée dans son fichier d'en tête bien sûr.) Comme le bouton ne l'appelle pas directement, j'ai pensé ne pas devoir mettre de (id) sender. J'ai essayé de le mettre d'ailleurs, mais comme cette méthode est également appelée lors de l'instanciation des boutons, et ailleurs encore... cela bloque l'ouverture du programme.
En fait, cette méthode : "calculeValeurs" est la plaque tournante du programme. Elle va être constamment employée. C'est pourquoi je pensais aux écouteurs, mais cela m'étonne quand même : mes classes sont capables de gérer deux ou trois float tout de même!! La structure du programme est tout de même simple.
- Vue: ce sont les boutons, champs de texte, etc.
- Modèle: il s'agit du code "métier"
- Contrôleur: le code qui fait le lien entre les deux.
Les méthodes d'action font forcément partie du Contrôleur.
Le stockage des données et les calculs se font forcément dans la couche Modèle. Les méthodes -calculeValeurs, -setValSat1, -setValBright1, et -setValGenerale doivent faire partie de cette couche et n'ont rien à faire dans un contrôleur:
Qui crée le modèle ?
En général, c'est le document (sous-classe de NSDocument). Il passe ensuite le modèle aux autre contrôleurs.
La synchronisation des vues et du modèle est du ressort du contrôleur. Lors d'un clic d'un bouton:
1) Le contrôleur appelle la méthode du modèle qui convient
2) Le contrôleur récupère le résultat dans le modèle et met à jour les vues.
Puisque le modèle est modifié à l'initiative du contrôleur, il n'est pas nécessaire (pour l'instant) que le contrôleur observe les modifications du modèle. Quand tu auras un tel besoin, tu pourras utiliser les notifications (NSNotificationCenter) ou le Key-Value Observing.
La première série de boutons permet de sélectionner des valeurs HSB (on les voit tout simplement), la méthode de calculs calcule des palettes suivant différents algorithmes, la seconde série de boutons affiche ces palettes. On doit ensuite pouvoir dessiner avec à l'écran en sélectionnant des couleurs dans la palette.
En effet, j'ai peut-être mal compris comment concevoir l'architecture même d'un programme Cocoa. En Java, je sur-spécialisais chaque classe. Dans le bouquin de Hillegass, j'ai cru comprendre que l'on résonnait différemment en Cocoa: une classe principale très centralisatrice communique avec toutes les autres, leur distribuant et récoltant d'elles les informations dont elles ont besoin.
Pour l'instant, mon architecture est :
AppController (qui dérive de NSView) crée les deux tableaux de boutons, gère les outlets des boutons IB, fait les calculs.
une classe de boutons A (celle qui sera utilisée en tableaux et qui montre des HSB)
une classe de boutons B (utilisée elle aussi en tableau, qui montre la palette) (ces deux classes ont une méthode de dessin propre, un drawRect à elles, indépendante de celle de l'AppController)
il y aura une classe "figure" stockant des valeurs pour le dessin(des points pour les NSBezierPath, des couleurs), et sans doute aussi une classe faisant ce dessin (à partir des informations données par un NSMutableArray de "figures") , liée à une ImageView dans IB.
Si je te comprends bien, il faudrait qu'une classe à part gère les calculs, classe qui serait appelée par AppController. C'est bien possible.
D'ailleurs, pour que mes tableaux de boutons s'affichent, j'ai dû appeler les méthodes les créant dans le "drawRect" de l'AppController. Bizarrement, la méthode "init" de l'AppController semble ne pas être appelée, ou plutôt les choses que j'instancie dedans semblent n'être pas enregistrées (je voulais y instancier un certain nombre de valeurs).
Bon, je vais essayer de trouver une doc, bien que j'ai déjà lu les documents Apple et un livre sur le sujet. C'est vrai que j'ai du mal à bien saisir cette nouvelle architecture. Je croyais avoir compris, mais dans les faits, cela ne marche pas comme prévu...
(je n'étais pas certain de mon archi d'ailleurs...)
Ce n'est pas une question de langage, c'est une question de méthodologie. Même en Java, je t'assure qu'on préfère la composition à l'héritage. ("Extend is Evil"). Tous les bouquins sérieux sur la POO insistent sur ce point.
Java et ObjC sont très similaires; ils sont beaucoup plus inspirés par Smalltalk que par C++.
L'héritage crée une dépendance forte entre deux classes. La composition oblige à définir précisément les interfaces, ce qui clarifie les dépendances d'un objet connecté à un autre.
Dans ces deux langages, l'héritage multiple n'existe pas (une classe ne peut hériter que d'une classe à la fois). Par contre, on peut définir des Interfaces en Java, qu'on appelle des Protocoles en ObjC.
Pas forcément dans le principe, mais c'est vrai dans les faits: un document est souvent lié à un fichier sur le disque. Il faut une classe centralisatrice (en général NSDocument), qui lit le fichier et construit la hiérarchie des objets grâce à son contenu.
Comme souligné par Ali, il y a un gros problème de conception: une vue (héritière de NSView) est un objet qui s'affiche à l'écran et réagit aux événements (clics, frappe...). Gérer des vues est le travail d'un contrôleur.
Un Contrôleur hérite directement de NSObject. Il existe les classes NSViewController et NSWindowController qui permettent de charger respectivement une vue et une fenêtre depuis un fichier .nib, mais le principe reste le même.
Les boutons doivent être créés et gérés par un Contrôleur.
J'ai quand même l'impression que tu te prends la tête pour rien. Est-ce que les boutons NSColorWell ne pourraient pas convenir ?
La classe Figure fait partie de la couche Modèle.
Ce schéma fonctionne, mais il implique de créer une NSImage et de dessiner dedans, puis de l'affecter à la NSImageView.
Tu verras qu'il est plus simple de créer une Vue (qui hérite donc de NSView) à laquelle le contrôleur passera une liste de Figures à dessiner dans sa méthode -[drawRect:].
L'initialiseur désigné pour NSView est -[initWithFrame:], pas -[init].
Cette locution bizarre est utilisée dans la doc pour préciser quelle méthode d'initialisation doit être appelée.
J'ai fait une classe NSView spéciale pour la première série de boutons, une autre pour la seconde série, l'AppController est maintenant un NSObject, j'ai mis le second NSView en IBOutlet de l'AppController et du premier, et maintenant tout marche comme il le faut.
Céroce, tu as peut-être raison concernant ma façon de compliquer les choses, mais une des raisons qui me porte vers Cocoa est la possibilité de créer des interfaces graphiques évoluées. Aussi autant apprendre à le faire tout de suite...
A ce sujet, Quartz a l'air puissant dans ce domaine. La doc montre des graphiques genre Interface Builder pour Quartz. Connaà®triez-vous une doc en français pour manipuler cela? (Ou bien je n'ai pas bien lu, ce qui est possible : je n'ai que survolé ce document)
Merci encore à tous. Votre site est super par ailleurs, une fois acquis un peu de métier, j'essaierai d'aider à mon tour.
Disons que c'est ce qu'il y a de plus difficile à faire. Tant que tu utilises des contrôles standard, c'est facile, mais leur personnalisation est difficile parce qu'Apple ne documente pas la manière de s'y prendre.
Ce n'est sûrement pas par ce bout-là que je conseillerais d'aborder Cocoa.
Tu parles de Quartz Composer ? ça n'a pas grand chose avec Quartz, hormis le nom.
Quartz Composer se trouve dans Developer/Applications. Les "compositions" peuvent être utilisées dans un projet Cocoa.
C'est par exemple utilisé dans PhotoBooth.
Je pense qu'ensuite, Quartz Composer donne une animation intégrable dans un autre soft?
Sinon, je me fais peu à peu à Cocoa. J'aime bien. Interface Bulder, lorsqu'on l'utilise "normalement" est également une bonne idée. En Java, bon nombre de projets prenaient plusieurs centaines de lignes de code simplement pour implémenter l'interface!!! Il n'y a pas à dire, IB est bienvenu.
Oui, un exemple avec Pulp Motion.