我正在創建一個鋼琴應用程序(用於OSX),它有一個屏幕鍵盤,顯示用戶在他們的合成鍵盤上正在播放的內容。一切都使用CoreMIDI框架進行連接。我創建了一些海關按鈕,通過在名爲PianoKey的課程中對NSButton進行繼承。該類可以看到如下:定製NSButton不能從CoreMIDI回調函數中工作
#import "PianoKey.h"
@implementation PianoKey
//updates the core animation layer whenever it needs to be changed
- (BOOL)wantsUpdateLayer {
return YES;
}
- (void)updateLayer {
//tells you whether or not the button is pressed
if ([self.cell isHighlighted]) {
NSLog(@"BUTTON PRESSED");
self.layer.contents = [NSImage imageNamed:@"buttonpressed.png"];
}
else {
NSLog(@"BUTTON NOT PRESSED");
self.layer.contents = [NSImage imageNamed:@"button.png"];
}
}
@end
「PianoKeys」以編程方式創建。未按下時,鋼琴鍵是藍色的,當它們被按下時,它們是粉紅色的(只是臨時的顏色)。如果我點擊屏幕上的按鈕,顏色開關就可以正常工作,但當我嘗試通過MIDI鍵盤播放時,它們不會改變。
一些注意事項: 1)MIDI鍵盤工作 2)我成功從鍵盤獲取MIDI數據。
a)本MIDI數據被傳遞到稱爲midiInputCallback的回調函數,如下所示: [從類AppController.m]
void midiInputCallback(const MIDIPacketList *list, void *procRef, void *srcRef) {
PianoKey *button = (__bridge PianoKey*)procRef;
UInt16 nBytes;
const MIDIPacket *packet = &list->packet[0]; //gets first packet in list
for(unsigned int i = 0; i < list->numPackets; i++) {
nBytes = packet->length; //number of bytes in a packet
handleMIDIStatus(packet, button);
packet = MIDIPacketNext(packet);
}
}
目的按鈕是按鈕的引用我按照AppController.h中的定義創建了編程式:
@property PianoKey *button; //yes, this is synthesized in AppController.m
b)回調函數調用一堆處理函數MIDI數據。如果筆記被檢測爲正在播放,這是我爲我設置的自定義按鈕突出......這可以在下面的功能可以看出:
void updateKeyboardButtonAfterKeyPressed(PianoKey *button, int key, bool keyOn) {
if(keyOn)
[button highlight:YES];
else
[button highlight:NO];
[button updateLayer];
}
[按鈕updateLayer]叫我updateLayer()方法來自PianoKey,但它不會改變圖像。有什麼我失蹤?看起來好像視圖或窗口沒有被更新,即使我的按鈕說它是「高亮顯示」。請幫忙!在此先感謝:)
我不完全確定......我不認爲這是從我一直在閱讀的主線上。再說一遍,CoreMIDI上的信息並不多,所以我不知道有時候該說些什麼:/ 你想讓我嘗試在回調方法中調用什麼? – 02fentym
我只在iOS中使用CoreMidi,但從我讀過的內容來看,GUI更新的線程問題是相同的。首先在你的'updateLayer'方法中放一個NSLog(或Cocoa等價)語句,看它是否被調用。如果是,那麼這是一個線程問題。在這種情況下,你想使用'performSelectorOnMainThread'。一個警告:由於鍵盤更新速度可能會比刷新速度快,因此每次調用更新可能毫無意義。在iOS中,有一種方法可以在每次刷新屏幕前調用。不知道在OSX中。也許嘗試'performSelectorOnMainThread'第一個廣告看看是否有效 –
好吧,我知道你在說什麼了。我現在有一個指向我的按鈕實例的指針,因爲我將它傳遞給了我的回調函數。如果我沒有這個參考,它會對我的按鈕對象一無所知。所以你是對的,這是一個線程問題。你如何使用'performSelectorOnMainThread'?我對這一切都很樂觀,但我快速學習(我認爲)。我應該將此作爲一個新問題嗎?順便說一句,如果我有一個我的按鈕的實例,我可以調用'updatelayer','performSelectorOnMainThread'將如何幫助? – 02fentym