【问题标题】:MacOS: How to launch gui QProcess and bring it to front?MacOS:如何启动 gui QProcess 并将其置于最前面?
【发布时间】:2020-12-10 20:34:43
【问题描述】:

我正在尝试使用 QProcess 运行 gui 应用程序,但默认情况下它是不活动的:

qint64 pid = 0;
QProcess::startDetached(executable, args, wd, &pid); //The app is in background

我试过activateWithOptions 并没有帮助:

qint64 pid = 0;
QProcess::startDetached(executable, args, wd, &pid);

NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:static_cast<pid_t>(pid)];
[app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; //The app is still in background

但如果我添加一个小延迟 activateWithOptions 按预期工作:

qint64 pid = 0;
QProcess::startDetached(executable, args, wd, &pid);

QThread::msleep(2000);
NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:static_cast<pid_t>(pid)];
[app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; //The app is in foreground!

但是QThread::msleep(2000) 看起来像一个肮脏的黑客,并且不会通过代码审查:)

所以,我的问题是:如何启动 gui 进程并在没有 hack 的情况下将其带到前面?

PS:我知道QProcess::startDetached("open", "-a " + executable); 可能有用,但它不允许指定工作目录,所以它不适合我

UPD:看来我需要等到应用程序finished launching,然后才能激活它。

【问题讨论】:

  • 如果您使用open -a script.sh 会发生什么,其中script.sh 是一个bash 脚本,然后会启动您想要的可执行文件?那行得通吗?否则,您可能想查看QTimer::singleShot 而不是QThread::msleep(2000)
  • @G.M.,据我了解,open 始终使用可执行路径作为工作目录。所以从脚本启动它并没有真正改变任何东西

标签: c++ macos qt cocoa


【解决方案1】:

我的解决方案:

    NSRunningApplication *waitForAppHandle(pid_t pid) const
    {
        forever {
            NSRunningApplication *app  = [NSRunningApplication runningApplicationWithProcessIdentifier: pid];
            if (app) 
                return app;
            }

            QThread::yieldCurrentThread();
        }
    }

    bool waitForLaunched(NSRunningApplication *app) const
    {

        forever {
            if ([app isFinishedLaunching]) {
                return;
            }

            QThread::yieldCurrentThread();
        }
    }

    void activate(pid_t pid)
    {
        NSRunningApplication *app = waitForAppHandle();
        waitForLaunched(app);

        [app activateWithOptions : NSApplicationActivateIgnoringOtherApps];
    }

    //...
    
    QProcess p;
    //...
    activate(p.processId());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2023-02-17
    相关资源
    最近更新 更多