gpt4 book ai didi

qt - 如何从 NSApplication 事件循环中启动 Go 的主要功能?

转载 作者:IT王子 更新时间:2023-10-29 01:08:19 28 4
gpt4 key购买 nike

我正在尝试添加 Sparkle进入我的 Qt ( binding for Go) 应用程序,使其可以自动更新。

问题:there is no popup dialog when running the latest version

这是代码:https://github.com/sparkle-project/Sparkle/blob/master/Sparkle/SUUIBasedUpdateDriver.m#L104

作为作者的原因pointed out NSAlert 需要运行循环才能工作。

我找到了一些文档:

因此,据我了解,我们必须在创建 QApplication 之前实例化 NSApplication

void NSApplicationMain(int argc, char *argv[]) {
[NSApplication sharedApplication];
[NSBundle loadNibNamed:@"myMain" owner:NSApp];
[NSApp run];
}

My Go 的主要功能是这样的:

func main() {
widgets.NewQApplication(len(os.Args), os.Args)

...
action := widgets.NewQMenuBar(nil).AddMenu2("").AddAction("Check for Updates...")
// http://doc.qt.io/qt-5/qaction.html#MenuRole-enum
action.SetMenuRole(widgets.QAction__ApplicationSpecificRole)
action.ConnectTriggered(func(bool) { sparkle_checkUpdates() })
...

widgets.QApplication_Exec()
}

问题:如何从 NSApplicationMain 事件循环中启动 Go 的 main 函数?

最佳答案

将 QApplication 与 Runloop 一起使用

关于如何将 QApplication 与 NSRunloop 一起使用的问题:您已经在这样做了。由于您使用的是 QApplication(而不是 QCoreApplication),因此您已经运行了一个 Runloop,

参见 http://code.qt.io/cgit/qt/qt.git/plain/src/gui/kernel/qeventdispatcher_mac.mmhttp://code.qt.io/cgit/qt/qt.git/plain/src/plugins/platforms/cocoa/qcocoaeventloopintegration.mm

证明

NSTimer 需要运行循环才能工作。因此,我们可以使用您在问题中引用的存储库中名为“widget”的现有示例 Qt 应用程序添加快速测试。

添加一个小的 Objective-C 测试类 TimerRunloopTest 和一个可以从 GO 调用的 C 函数包装器:

#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() }

ma​​in.go 的变化

在 app.Exec() 之前的末尾添加这一行:

runTimerRunloopTest()

构建并运行它

为我们的日志消息切换登录:

sudo log config --subsystem widget.example --mode level:debug

然后构建并运行它:

$(go env GOPATH)/bin/qtdeploy test desktop examples/basic/widgets

测试

在 macOS 控制台实用程序中,我们现在可以看到,显示了计时器滴答声,证明运行循环正在运行

NSAlert

然后您在问题中引用了 NSAlert 需要运行循环才能工作。我们已经证明我们有一个,但是明确地测试它是有道理的。

所以我们可以修改 timerrunlooptest.go 来通知它,我们也想再次链接 Cocoa,而不仅仅是 Foundation:

package main

/*
#cgo LDFLAGS: -framework Foundation
#cgo LDFLAGS: -framework Cocoa

void runTimerRunloopTest();
*/
import "C"

func runTimerRunloopTest() { C.runTimerRunloopTest() }

然后我们可以在TimerRunLoopTest的run方法中加入如下代码:

#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

native 警报按预期从 GO/QT 应用程序显示:

Native Alert from GO/QT

将 Qt 与 native 代码混合

虽然我们似乎能够以上述方式显示 native 警报,但在 QT 文档中有这样的提示可能有用也可能没有用:

Qt's event dispatcher is more flexible than what Cocoa offers, and lets the user spin the event dispatcher (and running QEventLoop::exec) without having to think about whether or not modal dialogs are showing on screen (which is a difference compared to Cocoa). Therefore, we need to do extra management in Qt to handle this correctly, which unfortunately makes mixing native panels hard. The best way at the moment to do this, is to follow the pattern below, where we post the call to the function with native code rather than calling it directly. Then we know that Qt has cleanly updated any pending event loop recursions before the native panel is shown.

参见 https://doc.qt.io/qt-5/macos-issues.html#using-native-cocoa-panels

还有一个小代码示例。

关于qt - 如何从 NSApplication 事件循环中启动 Go 的主要功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53772889/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com