2009-03-17 9 views
8

Descubrí cómo crear una ventana en Cocoa programáticamente pero no puedo encontrar la manera de reaccionar. La ventana no está reaccionando a una solicitud Salir o al hacer clic en un botón.¿Cómo puedo crear una GUI y reaccionar a los eventos de Cocoa programáticamente?

He intentado añadir el siguiente controlador y utiliza setDelegate/setTarget sin suerte:

@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

¿Por qué quieres hacer esto en primer lugar? En general, debe utilizar Interface Builder para crear la interfaz humana de su aplicación. –

+2

Estoy creando un puerto de otro kit de herramientas GUI. –

+0

@Chris: una razón para que investigue la creación de GUI programática es que cargué varios objetos con propiedades de un archivo, y tengo que hacer que todas las propiedades sean editables sin saber en tiempo de compilación cuántas hay, cómo están etiquetados y qué tipo de datos son (float, int, NSString, NSPoint, ...). Aunque creo que solo necesito completar una vista falsa vacía ya que otros elementos de la interfaz de usuario son estáticos. – LearnCocos2D

Respuesta

9

Necesita invocar - [NSApplication run] en lugar de - [[NSRunLoop currentRunLoop] ejecutar]. La razón debe ser claro si nos fijamos en la estructura básica del método:

- (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 encapsula mucho acerca de cómo obtener un evento, la forma de enviarlos y cómo actualizar las ventanas.

+0

Bien, gracias. Eso resuelve mi problema. ¿De dónde obtuviste este código fuente? Parece que incluso puedo implementar mi propio ciclo de ejecución en alguna parte y usar esta lógica proporcionada. –

+1

he creado este código para mi entrada en el blog: http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html Reconstruí este método mediante la lectura de la documentación para NSApplication estrechamente y adivinar los pasos implicados en absoluto hasta que se trabajó. –

3

He encontrado la manera de crear una ventana en Cocoa programación ...

¿Por qué? ¿Por qué no solo hacer una punta?

La ventana no está reaccionando a una solicitud de salir o haga clic en el botón.

¿Cómo saldrías de una ventana? Esto no es Windows 3; las aplicaciones pueden tener varias ventanas en Mac OS X. Por lo tanto, cerrar una ventana y salir de una aplicación son acciones separadas.

[[NSRunLoop currentRunLoop] run];

Salvo en circunstancias excepcionales, que ejecuta el bucle de ejecución es el trabajo de NSApplication, y usted debe dejar eso a ella. Use NSApplicationMain o -[NSApplication run] para indicarle a la aplicación que se ejecute.

+0

- Estoy portando otro kit de herramientas GUI (escrito en otro lenguaje de programación) a la Mac. Entonces, la GUI es muy dinámica y no creo que tenga sentido tener un archivo NIB. - Salir: a través del menú de la aplicación - Llamar ejecutar en la aplicación hace el truco, gracias! Gracias. –

2

Excelente pregunta. Creo que Matt Gallagher ya lo respondió, pero si quieres ir más allá con esto, tendrás que profundizar en el event-handling documentation de Apple. Tenga en cuenta que hacer todo de forma programática requerirá una comprensión sólida de cocoa fundamentals.

0

Pasé un día entero buscando respuestas a la parte de la GUI y el Menú de esta pregunta. No hay muchas respuestas actuales y concisas para la pregunta. Entonces, después de resolverlo por mí mismo, publiqué una respuesta que aborda esto en Stack aquí: Cocoa GUI Programmatically. Agregué una referencia aquí para ayudar a los miembros de la comunidad que buscan las mismas respuestas.

Cuestiones relacionadas