【问题标题】:Multiprocessing Qt app: How can I limit it to a single icon in the MacOS/X Dock?多处理 Qt 应用程序:如何将其限制为 MacOS/X Dock 中的单个图标?
【发布时间】:2013-06-04 08:44:56
【问题描述】:

我有一个 Qt 应用程序(出于此问题范围之外的原因)将其每个窗口作为单独的进程启动。

这工作正常,但在 MacOS/X 下,每个窗口/进程在 Dock 中显示为单独的条目。因此,当用户打开十几个窗口时,Docks 中有十几个相同的图标,这不是很有帮助(因为很难分辨哪个是哪个,并且图标开始变小)。

有没有办法告诉 Dock 将所有这些进程组合在一个 Dock 图标下? (Mac 专用的 API 就可以了)

【问题讨论】:

    标签: macos qt multiprocessing dock


    【解决方案1】:

    您可以使用以下 sn-p 隐藏未活动进程的 Dock 磁贴:

     - (void)applicationWillResignActive:(NSNotification *)notification
    {
        ProcessSerialNumber psn = {0, kCurrentProcess};
        TransformProcessType(&psn, kProcessTransformToBackgroundApplication);
        if([self.window isVisible])
        {
            [self.window performSelector:@selector(orderFrontRegardless) withObject:nil afterDelay:0.05];
        }
    }
    
    - (void)applicationWillBecomeActive:(NSNotification *)notification
    {
        ProcessSerialNumber psn = {0, kCurrentProcess};
        TransformProcessType(&psn, kProcessTransformToForegroundApplication);
        SetFrontProcessWithOptions(&psn, kSetFrontProcessCausedByUser);
    }
    

    只需将上述代码添加到您的应用委托中,当进程退出活动时,应用的 Dock 图标就会消失。
    要在进程转换为 UIElement 应用程序后保持窗口可见,请发送orderFrontRegardless 消息。 (我知道这很 hacky - 但这一定是非标准窗口/进程处理的代价)

    也许您还应该维护一个 Dock 菜单,允许您的用户选择隐藏的窗口。
    您可以从“主”应用程序中动态添加条目。详细信息可以在 Dock Tile 编程指南的"Dynamically Adding Menu Items With the Application Delegate" 部分找到。

    更新:
    我稍微更改了上面的代码示例,因为以前的方法在重新激活应用程序后导致主菜单无响应。

    【讨论】:

    • 这会不会也遇到进程进入UIElementApplication模式时我的窗口的菜单栏消失的问题?
    • 否,因为一旦应用再次激活(例如通过单击窗口),该进程就会自动转换为前台进程。不过,您将不得不找到关闭/隐藏窗口的解决方案。您可以通过将上述代码放入空 Xcode 项目的应用委托中轻松测试上述代码的行为。
    • 我用一个空的 Xcode 项目构建了上面的代码...当我在窗口外单击时,停靠图标消失了,但是当我再次给窗口焦点时,菜单栏不起作用: 我可以看到它,但点击它没有效果(即菜单没有下拉)。 :(
    • 我更新了代码 - 你能再试一次吗?在将应用程序发送到后台时,我将 TransformProcessType 参数更改为 kProcessTransformToBackgroundApplication,并在将其置于前台时添加了对 SetFrontProcessWithOptions 的手动调用。
    • 现在效果更好了,虽然在窗口失去焦点时会有轻微的闪烁。我会看看我能用这个做什么,谢谢!
    【解决方案2】:

    致电QSystemTrayIcon::hide()

    如果这不起作用,您可以尝试以下方法:


    使用NSApplicationsetActivationPolicy:方法

    方式一:[NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory];

    方式二:[NSApp setActivationPolicy: NSApplicationActivationPolicyProhibited];


    使用LSUIElement(LSUIElement=1)

    你也可以把它放在你的 pfile 中:<key>LSUIElement</key> <string>1</string> 或制作 Qt do it for you


    Qt forums 上也有一些关于 OSX 菜单 的讨论。此外,您可以尝试使用 QFocusEvent 来检查应用何时失去/获得焦点,然后相应地更新菜单


    来源

    【讨论】:

    • 这不是我所希望的,但我认为我可以让它工作——特别是我可以默认情况下让所有窗口停靠窗口隐藏(使用 Info.plist)然后只在其中一个上调用 setActivationPolicy .... 棘手的部分将是确保在关闭一个窗口后保留一个停靠图标。因此,除非在接下来的一两天内出现另一个(更好的)答案,否则我会将赏金奖励给这个人。
    • 哦,麻烦了——我之前的评论中描述的技术可以将窗口的图标保持在 Dock 之外,但它的副作用是当窗口有焦点——取而代之的是,菜单栏会继续显示与之前获得焦点的任何应用相关的菜单内容。
    • @JeremyFriesner 在 Qt 论坛上有一些关于菜单的讨论:qt-project.org/forums/viewthread/2416。不过,我不确定这是否有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    相关资源
    最近更新 更多