2009-03-17 15 views
8

Ho scoperto come creare una finestra in Cocoa a livello di codice, ma non riesco a capire come reagire agli eventi. La finestra non reagisce a una richiesta di uscita o al clic del pulsante.Come posso creare una GUI e reagire agli eventi Cocoa a livello di programmazione?

Ho provato ad aggiungere il seguente controller e utilizzato setDelegate/setTarget senza fortuna:

@interface AppController : NSObject { 
    } 
    - (IBAction)doSomething:(id)sender; 
    @end 

    @implementation AppController 
    - (IBAction)doSomething:(id)sender; 
    { 
     printf("Button clicked!\n"); 
    } 
    @end 

    int main(int argc, char **args){ 
     NSRect frame = NSMakeRect(0, 0, 200, 200); 

     AppController *controller = [[AppController alloc] init]; 

>  [[NSApplication sharedApplication] setDelegate:controller]; 
     NSWindow* window = [[NSWindow alloc] initWithContentRect:frame 
              styleMask:NSBorderlessWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask 
              backing:NSBackingStoreBuffered 
              defer:NO]; 
     [window setBackgroundColor:[NSColor blueColor]]; 

     NSButton *button = [ [ NSButton alloc ] initWithFrame: NSMakeRect(30.0, 20.0, 80.0, 50.0) ]; 
     [ button setBezelStyle:NSRoundedBezelStyle]; 
     [ button setTitle: @"Click" ]; 
>  [ button setAction:@selector(doSomething:)]; 
>  [ button setTarget:controller]; 
     [ [ window contentView ] addSubview: button ]; 

     [window makeKeyAndOrderFront:NSApp]; 

     [[NSRunLoop currentRunLoop] run]; 
     return 0; 
    } 
+1

Perché vuoi fare questo in primo luogo? In generale, è necessario utilizzare Interface Builder per creare l'interfaccia utente dell'applicazione. –

+2

Sto creando una porta di un altro toolkit della GUI. –

+0

@Chris: una ragione per me per esaminare la creazione della GUI programmatica è che carico un numero di oggetti con proprietà da un file, e devo rendere modificabili tutte le proprietà senza sapere al momento della compilazione quante sono, come sono etichettati e quale tipo di dati sono (float, int, NSString, NSPoint, ...). Anche se penso che ho solo bisogno di riempire una vista fittizia vuota dal momento che altri elementi dell'interfaccia utente sono statici. – LearnCocos2D

risposta

9

È necessario richiamare - [Esecuzione NSApplication] anziché - [[NSRunLoop currentRunLoop] run]. Il motivo dovrebbe essere chiaro se si guarda alla struttura di base del metodo:

- (void)run 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    [self finishLaunching]; 

    shouldKeepRunning = YES; 
    do 
    { 
     [pool release]; 
     pool = [[NSAutoreleasePool alloc] init]; 

     NSEvent *event = 
      [self 
       nextEventMatchingMask:NSAnyEventMask 
       untilDate:[NSDate distantFuture] 
       inMode:NSDefaultRunLoopMode 
       dequeue:YES]; 

     [self sendEvent:event]; 
     [self updateWindows]; 
    } while (shouldKeepRunning); 

    [pool release]; 
} 

NSApplication incapsula molto su come ottenere un evento, come di spedire loro e come aggiornamento di Windows.

+0

Bello, grazie. Questo risolve il mio problema. Da dove hai preso questo codice sorgente? Quindi sembra che io possa anche implementare il mio proprio ciclo di esecuzione da qualche parte e utilizzare questa logica fornita. –

+1

Ho creato questo codice per il mio post del blog: http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html Ho ricostruito questo metodo leggendo la documentazione per NSApplication da vicino e indovinando a tutti i passaggi impliciti fino a quando lavorato. –

3

ho scoperto come creare una finestra a Cocoa programmazione ...

Perché? Perché non fare un pennino?

La finestra non risponde a una richiesta di uscita o al clic del pulsante.

Come chiudere una finestra? Questo non è Windows 3; le applicazioni possono avere più finestre su Mac OS X. Come tali, chiudere una finestra e chiudere un'applicazione sono azioni separate.

[[NSRunLoop currentRunLoop] run];

Tranne in rari casi, l'esecuzione del ciclo di esecuzione è il lavoro di NSApplication e dovresti lasciarlo. Utilizzare NSApplicationMain o -[NSApplication run] per indicare all'applicazione di essere eseguita.

+0

- Sto trasferendo su Mac un altro toolkit GUI (scritto in un altro linguaggio di programmazione). Quindi la GUI è molto dinamica e non penso che ci sia un punto nell'avere un file NIB. - Esci: tramite il menu dell'applicazione - Chiamare l'esecuzione sull'applicazione fa il trucco, grazie! Grazie. –

2

Ottima domanda. Penso che Matt Gallagher abbia già risposto, ma se vuoi andare oltre, dovrai approfondire il numero event-handling documentation di Apple. Ricorda che fare tutto programmaticamente richiederà una solida conoscenza di cocoa fundamentals.

0

Ho trascorso un'intera giornata alla ricerca di risposte alla GUI e alla parte del menu di questa domanda. Non ci sono molte risposte attuali e concise là fuori per la domanda. Quindi, dopo aver risolto per me stesso, ho postato una risposta che affronta questo su Stack qui: Cocoa GUI Programmatically. Aggiungo un riferimento ad esso qui per aiutare i membri della comunità che stanno scavando intorno per le stesse risposte.

Problemi correlati