2009-03-17 1 views
8

Cocoaでウィンドウをプログラムで作成する方法を知りましたが、イベントへの対応方法を理解することはできません。ウィンドウが終了要求またはボタンクリックに反応しません。GUIを作成してCocoaイベントにプログラム的に反応させるにはどうすればよいですか?

私は、次のコントローラを追加しようとしたし、運なしsetDelegate /がsetTargetを使用:

@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

なぜこれを最初にやりたいのですか?一般に、Interface Builderを使用してアプリケーションのヒューマンインタフェースを作成する必要があります。 –

+2

私は別のGUIツールキットのポートを作成しています。 –

+0

@Chris:私がプログラムによるGUI作成を調べる理由の1つは、ファイルからプロパティを持つオブジェクトをいくつか読み込み、コンパイル時に何個あるか、どのように存在するかを知らずにすべてのプロパティを編集可能にする必要があることですそれらのデータ型(float、int、NSString、NSPoint、...)が含まれます。私は空のダミービューを埋める必要があるだけだと思う​​が、他のUI要素は静的なので、 – LearnCocos2D

答えて

9

- [[NSRunLoop currentRunLoop] run]の代わりに[NSApplication run]を呼び出す必要があります。あなたがこの方法の基本的な構造を見れば理由は明確にする必要があります:

- (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のは、それらをディスパッチするとウィンドウを更新する方法をどのように、イベントを取得する方法について多くをカプセル化します。

+0

ニース、ありがとう。それが私の問題を解決する。どこからこのソースコードを入手しましたか? 私は自分の実行ループをどこかに実装し、この提供されたロジックを使用することもできます。 –

+1

私のブログ記事のためにこのコードを作成しました:http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html NSApplicationのドキュメントをよく読んで、それまでのすべての暗黙のステップを推測することで、このメソッドを再構築しました働いた。 –

3

私が...プログラムで

なぜココアでウィンドウを作成する方法を見つけましたか?なぜペン先を作ってみませんか?

ウィンドウが終了要求またはボタンクリックに反応しません。

どのようにウィンドウを終了しますか?これはWindows 3ではありません。アプリケーションはMac OS X上に複数のウィンドウを持つことができます。したがって、ウィンドウを閉じるとアプリケーションを終了することは、別々のアクションです。

[[NSRunLoop currentRunLoop] run];

まれに例外を除いて、実行ループの実行はNSApplicationのジョブであり、そのままにしておく必要があります。アプリケーションに実行を指示するには、NSApplicationMainまたは-[NSApplication run]を使用します。

+0

- 別のGUIツールキット(別のプログラミング言語で書かれたもの)をMacに移植します。だから、GUIは非常に動的であり、NIBファイルを持っている点はないと思います。 - 終了:アプリケーションメニューを介して - アプリケーションで実行を呼び出すと、トリック、ありがとう!おかげさまで –

2

優秀な質問です。私はMatt Gallagherがすでにそれに答えていると思うが、これをさらに進めたいのであれば、Appleのevent-handling documentationについて掘り下げなければならないだろう。プログラムですべてを実行するには、cocoa fundamentalsを確実に理解する必要があります。

0

私はこの質問のGUIとメニュー部分への回答を探して一日を過ごしました。そこには多くの最新の簡潔な答えが質問にはありません。だから自分で解決した後、私はスタックにこれを扱う答えを投稿しました:Cocoa GUI Programmatically。私は同じ回答のために掘り下げているコミュニティメンバーを助けるためにここに紹介を追加します。

関連する問題