У меня есть многопоточное приложение Linux C ++ без графического интерфейса, в котором я хочу использовать случайный элемент управления Cocoa, а именно диалоги загрузки / выгрузки файлов и оповещения.
I 'Я далек от эксперта по Какао, но смог создать несколько тестовых / демонстрационных приложений Objective-C ++, которые работали как задумано.
Теперь, когда я интегрировал код Какао в свое приложение, кажется, что яу меня проблемы с публикацией вещей в основной ветке GUI.Может быть, я не сделал то, что мне нужно было сделать, чтобы создать его, я действительно не уверен.Вот что у меня в файле .mm:
#ifdef MACOS
@interface CocoaInterface : NSObject
{
}
- (id) init;
- (void) ShowFileUploadDialog;
- (void) ShowFileDownloadDialog;
@end
@implementation CocoaInterface
- (id) init
{
cout << "Creating NSAutoreleasePool" << endl;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
cout << "Creating NSApplication" << endl;
NSApplication* app = [[NSApplication alloc] init];
cout << "Calling NSApplication::finishLaunching" << endl;
[app finishLaunching];
[super init];
return self;
}
- (void) ShowFileUploadDialog
{
cout << "Entering ShowFileUploadDialog" << endl;
if ([NSThread isMainThread])
{
// Show file dialog
cout << "Calling NSRunAlertPanel" << endl;
NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
}
else
{
//NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
cout << "Redirecting ShowFileUploadDialog call to main thread." << endl;
[self performSelectorOnMainThread:@selector(ShowFileUploadDialog) withObject:nil waitUntilDone:YES];
}
}
- (void) ShowFileDownloadDialog
{
cout << "Entering ShowFileDownloadDialog" << endl;
if ([NSThread isMainThread])
{
// Show file dialog
cout << "Calling NSRunAlertPanel" << endl;
NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
}
else
{
//NSRunAlertPanel(@"This is a test", @"Does it work?", @"Yes", @"No", @"");
cout << "Redirecting ShowFileDownloadDialog call to main thread." << endl;
[self performSelectorOnMainThread:@selector(ShowFileDownloadDialog) withObject:nil waitUntilDone:YES];
}
}
@end
#endif
Я вызываю это из кода, который есть в различных потоках, обрабатывающих входящие сетевые сообщения:
cout << "Creating CocoaInterface." << endl;
CocoaInterface* interface = [[CocoaInterface alloc] init];
cout << "Calling CocoaInterface::ShowFileDownloadDialog." << endl;
[interface ShowFileDownloadDialog];
Это зависаетпытаясь выполнить селектор - как будто он никогда не сможет найти основной поток.Обратная трассировка в GDB показывает, что я ожидаю семафора навсегда.
Когда я раскомментирую вызов NSRunAlertPanel перед вызовом executeSelectorOnMainThread, я получаю белый блок в форме диалога, но он не полностью рисует или обрабатываетлюбые сообщения, предположительно потому, что они не находятся в главном потоке графического интерфейса.
Кажется, что у меня нет нужного потока графического интерфейса или я просто не могу получить его там, где я нахожусь.Я подозреваю, что я что-то пропустил при инициализации.Есть предложения?