Использование QApplication вместе с Runloop
Относительно вашего вопроса, как использовать ваше QApplication вместе с NSRunloop: вы уже делаете это.Поскольку вы используете QApplication (а не QCoreApplication), у вас уже запущен Runloop,
см. http://code.qt.io/cgit/qt/qt.git/plain/src/gui/kernel/qeventdispatcher_mac.mm и http://code.qt.io/cgit/qt/qt.git/plain/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm
Proof
Для работы NSTimer необходим цикл выполнения.Таким образом, мы могли бы добавить быстрый тест с существующим примером приложения Qt под названием 'widget' из репозитория, на который вы указали в своем вопросе.
Добавление небольшого класса Objective-C класса TimerRunloopTest с оберткой функции C, которую можно вызватьGO:
#import <Foundation/Foundation.h>
#include <os/log.h>
@interface TimerRunloopTest : NSObject
- (void)run;
@end
void runTimerRunloopTest() {
[[TimerRunloopTest new] run];
}
@implementation TimerRunloopTest
- (void)run {
os_log_t log = os_log_create("widget.example", "RunloopTest");
os_log(log, "setup happening at %f", NSDate.timeIntervalSinceReferenceDate);
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(timerTick:)
userInfo:nil
repeats:YES];
}
- (void)timerTick:(NSTimer *)timer {
os_log_t log = os_log_create("widget.example", "RunloopTest");
os_log(log, "timer tick %f", NSDate.timeIntervalSinceReferenceDate);
}
@end
GO аналог timerrunlooptest.go
package main
/*
#cgo LDFLAGS: -framework Foundation
void runTimerRunloopTest();
*/
import "C"
func runTimerRunloopTest() { C.runTimerRunloopTest() }
Изменение main.go
Наконец перед app.Exec () добавьте эту строку:
runTimerRunloopTest()
Постройте и запустите его
Включите вход в систему для наших сообщений регистрации:
sudo log config --subsystem widget.example --mode level:debug
После этого соберите и запустите его:
$(go env GOPATH)/bin/qtdeploy test desktop examples/basic/widgets
Тест
В утилите MacOS Console теперь мы можем видеть, что показываются отметки таймера, подтверждая, чтозапускается цикл выполнения
NSAlert
Тогда вы указали в своем вопросе, что для работы NSAlert нужен цикл выполнения.Мы уже доказали, что он у нас есть, но его проверка явно имеет смысл.
Таким образом, мы можем изменить timerrunlooptest.go, чтобы сообщить ему, что мы хотим связывать также с Cocoa, а не только с Foundation:
package main
/*
#cgo LDFLAGS: -framework Foundation
#cgo LDFLAGS: -framework Cocoa
void runTimerRunloopTest();
*/
import "C"
func runTimerRunloopTest() { C.runTimerRunloopTest() }
Затем мы можем добавить следующий код в метод runTimerRunLoopTest:
#import <Cocoa/Cocoa.h>
...
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = @"Message";
alert.informativeText = @"Info";
[alert addButtonWithTitle:@"OK"];
[alert runModal];
Результат
После выполнения
$(go env GOPATH)/bin/qtdeploy test desktop examples/basic/widgets
собственный оповещение отображается из приложения GO / QT, как и ожидалось:
Смешивание Qt с собственным кодом
Хотя мы, похоже, можем отображать нативные предупреждения вкак описано выше, в документах QT есть эта подсказка, которая может или не может быть полезной:
Диспетчер событий Qt является более гибким, чем то, что предлагает Какао, и позволяет пользователю вращать диспетчер событий (и запуск QEventLoop :: exec) без необходимости думать о том, отображаются ли модальные диалоги на экране (что отличается от какао).Поэтому нам нужно сделать дополнительное управление в Qt для правильной обработки, что, к сожалению, затрудняет смешивание нативных панелей.На данный момент лучший способ сделать это - следовать приведенному ниже шаблону, где мы публикуем вызов функции с собственным кодом, а не вызываем ее напрямую.Затем мы знаем, что Qt корректно обновил все ожидающие рекурсии цикла событий перед отображением собственной панели.
see https://doc.qt.io/qt-5/macos-issues.html#using-native-cocoa-panels
Для этого также есть небольшой пример кода.