SubMenu dynamique
muqaddar
Administrateur
Salut,
Je voudrais créer un nsmenu dynamique mais j'ai des erreurs :
2005-03-01 12:01:22.094 alphaProject[3459] *** Assertion failure in -[NSMenuItem initWithTitle:action:keyEquivalent:], Menus.subproj/NSMenuItem.m:116
2005-03-01 12:01:22.095 alphaProject[3459] Exception raised during posting of notification. Ignored. exception: Invalid parameter not satisfying: charCode != nil
Le code :
J'ai mis "nil" à action pour l'instant mais je ne crois pas que ce soit ça qui foire.
J'ajoute que [dico objectForKey:@myKey] me renvoie bien une string quand je fais un NSLog.
merci
Je voudrais créer un nsmenu dynamique mais j'ai des erreurs :
2005-03-01 12:01:22.094 alphaProject[3459] *** Assertion failure in -[NSMenuItem initWithTitle:action:keyEquivalent:], Menus.subproj/NSMenuItem.m:116
2005-03-01 12:01:22.095 alphaProject[3459] Exception raised during posting of notification. Ignored. exception: Invalid parameter not satisfying: charCode != nil
Le code :
[subMenu addItemWithTitle:[dico objectForKey:@"myKey"] action:nil keyEquivalent:nil];
J'ai mis "nil" à action pour l'instant mais je ne crois pas que ce soit ça qui foire.
J'ajoute que [dico objectForKey:@myKey] me renvoie bien une string quand je fais un NSLog.
merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
initWithTitle:action:keyEquivalent:
- (id)initWithTitle:(NSString *)itemName action:(SEL)anAction keyEquivalent:(NSString *)charCode
Returns an initialized instance of an NSMenuItem. The arguments itemName and charCode must not be nil
j'ai fait ça :
ça marche.
une simple chaine vide @"" aurait fait l'affaire aussi.
J'ai un soucis pour mon action. Je dois y envoyer un argument en plus... par le sélecteur or c'est pas possible. Comment faire ?
Une idée ?
pour y ajouter d'autres paramètres, tu pourrais lier un objet (un array d'objets si tu en a plusieurs) au menuitem avec setRepresentedObject et le récupérer avec representedObject dans ton action...
edit:
HA HA HA j'ai réussi à griller Renaud !!!! >:D :P :P
[tt][mi setRepresentedObject:tonArg];[/tt]
que tu repèches comme suit
[tt]-(void)monAction:(id)sender {
   obj = [sender representedObject];
}[/tt]
Attention ceci dit, le representedObject n'est pas retenu par le menu item, donc veille à ce qu'il soit retenu ailleurs (par exemple dans un tableau variable d'instance).
[EDIT] Grilled, la prochaine fois je me relirai pas na!
J'ai compris. :-)
T'es sûr de ton coup là Â
Si l'objet n'était pas retenu j'aurais de sérieux problèmes en Java (weak reference) et ce n'est pas le cas.
ça me donne:
1
2
Pas de plantage.
++
merci
Voir aussi le setTarget: si tu souhaites avoir le "sélecteur" dans une autre classe...
J'ai lié ma barre de menu dans IB et elle est accessible avec ce pointeur: [tt]menuFile[/tt]
Mon problème est que ça ne marche pas:
J'ai même essayé :
mais ça ne marche toujours pas...
Où j'ai faux???? :why?: :why?:
[tt]
NSLog(@submenu:%@",[[menuFile itemWithTag:18] submenu]);
[/tt]
Je passe par la méthode initWithTitle plutôt que par addItemWithTitle, car avec cette dernière les actions ne sont pas exécutées, sûrement de par l'absence de la target je pense.
[tt]
-(void)awakeFromNib
{
NSMenuItem *nouveauItem;
// Initialisation du submenu
NSMenuItem *menuItem18=[monMenu itemWithTag:18];
NSMenu *monSubmenu=[[NSMenu alloc] initWithTitle:@""];
// Ajout à monSubmenu de l'item1
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 1 action:@selector(action1) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Ajout à monSubmenu de l'item2
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 2 action:@selector(action2) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Ajout à monSubmenu de l'item3
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 3 action:@selector(action3) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Attachement de monSubmenu au menuItem18
[menuItem18 setSubmenu:monSubmenu];
[monSubmenu release];
}
-(void)action1
{
NSLog(@Action 1);
}
-(void)action2
{
NSLog(@Action 2);
}
-(void)action3
{
NSLog(@Action 3);
}
[/tt]
[Fichier joint supprimé par l'administrateur]
ta solution ne marche pas! :-\\
Ce n'est pas une solution, mais un simple log...Et puis en plus qui n'a plus d'intérêt avec ce que je t'ai mis par la suite.
Tu n'as donc pas regardé le projet d'exemple que je t'ai mis en attachement ici ? ::)
[tt]-(void)awakeFromNib
{
NSMenuItem *nouveauItem;
// Initialisation du submenu
NSMenuItem *menuItem18=[monMenu itemWithTag:18];
NSMenu *monSubmenu=[[NSMenu alloc] initWithTitle:@""];
// Ajout à monSubmenu de l'item1
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 1 action:@selector(action1) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Ajout à monSubmenu de l'item2
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 2 action:@selector(action2) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Ajout à monSubmenu de l'item3
nouveauItem=[[NSMenuItem alloc] initWithTitle:@Item 3 action:@selector(action3) keyEquivalent:@""];
[nouveauItem setTarget:self];
[monSubmenu addItem:nouveauItem];
[nouveauItem release];
// Attachement de monSubmenu au menuItem18
[menuItem18 setSubmenu:monSubmenu];
[monSubmenu release];
}
-(void)action1
{
NSLog(@Action 1);
}
-(void)action2
{
NSLog(@Action 2);
}
-(void)action3
{
NSLog(@Action 3);
}[/tt]
Je regarde l'exemple
et impossible de l'ajouter. Dans IB j'ai mis un élément de menu normal (sans sous menu) avec le tag 18.
Dans le code j'ai fait un bête copier coller de l'exemple, et ça ne marche pas.
Il n'y a pas un moyen d'acceder au menu de l'application sans un Outlet?
Eddy a mis le doigt dessus plusieurs posts précédents, mais je ne pense pas que tu as tout compris.
menuFile est ton outlet qui pointe sur le submenu "File" (ou "Fichier").
Dans ce submenu "File", tu as un second submenu dont le tag est 18. Apparemment, ce submenu est du style "Open with..." ("Ouvrir avec...").
Je ne sais pas trop ce que tu veux faire... Mais 2 cas peuvent se présenter :
1. ton submenu est initialisé 1 seul fois (en début d'application par exemple).
2. ton submenu est dynamique, et son contenu évolue toujours (en fonction de ce que tu fais dans ton appli).
Le premier cas est le plus simple : sois tu créés des menus-item dans IB et tu les inclues dans ton submenu... soit tu fais tout ça par programmation dans le awakeFromNib de ton contrôleur par exemple :
Pour le second cas, tu dois mettre un delegate à ton submenu, et dans la classe delegate, tu dois implémenter la méthode :
[tt]- (void)menuNeedsUpdate:(NSMenu *)menu[/tt]
Le delegate va se charger de recréer/reremplir dynamiquement le menu attaché au submenu en fonction de critères à l'instant T, au moment où le système va afficher le contenu du submenu :
Bref, que du classique...
.
Merci quand même. Ca marche nickel
Cette boucle ne va pas bien:
[tt] for (ix=0; ix<[menu numberOfItems]; ix++) [menu removeItemAtIndex:0];[/tt]
La première fois elle supprime tout, la seconde il en reste 1, et après il en reste 2. Comment faire pour être sûr qu'elle supprime tout??
Un coup des plus classiques !
soit un tableau de 5 éléments tab[0] à tab[4] que tu veux vider. Tu commences avec idx = 0, tu supprimes tab[idx] donc tab[0]... mais là que se passe-t-il ? les éléments se décalent dans le tableau ! tab[0] est supprimé, du coup tab[1] devient tab[0], la case 2 passe en position 1, la case 3 en position 2, etc.
Du coup au coup d'après avec idx++ donc idx=1, tu supprimes tab[1]... et le tab[0] (qui était l'ancien tab[1] qui a été décalé) ne sera pas supprimé...
La solution ? Allez, un petit effort, tu peux la trouer tout seul !
Il semblerait que [tt][menu numberOfItems][/tt] soit évalué plus d'une fois...
.
Sauf que là , cher ami, on ne joue pas avec l'index !
Allez, un petit effort, et tu comprendras !
.
Ce n'est pas le même problème certes, mais il est très similaire, et la boucle classique : telle qu'on l'écrit d'habitude quand on fait une suppression d'élément d'un (pseudo-)tableau aurait résolu le problème
Maintenant tant qu'à faire un truc bien, autant faire un simple : c'est aussi bien
Oh oh joli celle là Ca me "trouve" le c*l ;D Â :)
PS à Renaud : ouais t'as raison, et c'est de ta faute en fait
[EDIT] Renaud : tricheur !
Mais j'ai bien essayé différente boucle et ça donne le même résultat. Je test avec le "while".
Merci beaucoup
[edit] ça va mieux avec le while
Lorsque l'on supprimer un sous-menu, est-ce que cela efface de la mémoire les items qui étaient dans ce sous-menu ? Comment faire pour supprimer ces items sinon ?