我正在运行启动流程的Qt应用程序(Qt助手)
当应用程序在OSX上运行时,进程窗口显示在调用者窗口后面...
我怎样才能把它带到前面?
Qt文档中的代码:
QProcess *process = new QProcess();
QStringList args;
args << QLatin1String("-collectionFile")
<< QLatin1String("mycollection.qhc");
//<< QLatin1String("-enableRemoteControl"); // can't use this, help freezes... but still starts in background! ... this is apparently a bug in Qt solved in Qt 5.4 (see Note) which I cannot use, but not relevant for current problem
process->start(QLatin1String("Assistant.app"), args);
if (!process->waitForStarted())
return;
关于不使用“-enableRemoteControl”的注意事项 - 请参阅question
标记为重复/投票已关闭指向以分离方式启动进程的示例。尝试它并没有解决问题 - 此外,帮助必须是应用程序的子进程。
根据评论/发布回答更新
尝试
QString app = "path/to/Assistant"; // since I use the copy from inside bundle
QString helpfile = "path/to/helpfile";
QString cmd = QString("open -a '%1' --args '-collectionFile' '%2'").arg(app).arg(helpFile);
qDebug()<<cmd;
m_helpProcess->start(cmd);
m_helpProcess->waitForStarted();
if (m_helpProcess->state() == QProcess::Running)
qDebug()<<"help started";
else
qDebug()<<m_helpProcess->errorString();
结果:
help started (but the window doesn't show at all, I think it gives an error and closes)
(如果我将路径从cmd
复制到Terminal
,运行完美,以便参数看起来正确......)
尝试使用osascript后更新:
在上面的代码启动助手后,我添加了(许多版本的activateScript之一)
Q_PID pid = m_helpProcess->pid();
QString activateScript = "tell application System Events to perform action \"AXRaise\" of application " + app + "\n";
QString activateScript = "tell application System Events to perform action \"AXRaise\" of window with title \"My App Help\"\n";
QString activateScript = "tell application " + app + " to activate\n";
QString activateScript = "tell application Assistant activate\n";
QString activateScript = QString("tell application \"System Events\" \n") +
QString("set (frontmost of processes whose id is ") + QString::number(pid) + QString(") to true\n") +
QString("end tell\n");
QString activateScript = QString("tell application \"System Events\" \n") +
QString("tell process whose id is ") + QString::number(pid) + QString(") to activate\n") +
QString("end tell\n") + QString("end tell\n");
QString activateScript = QString("tell application \"System Events\" to perform action \"AXRaise\"") +
QString("of application whose id is ") + QString::number(pid) +
QString("end tell\n");
QString activateScript = QString("tell process whose id is ") + QString::number(pid) + QString(") to activate\n") +
QString("end tell\n");
QString osaScript = "/usr/bin/osascript";
QStringList osaArguments;
osaArguments << "-l" << "AppleScript";
QProcess p;
p.start(osaScript, osaArguments);
p.write(activateScript.toUtf8());
p.closeWriteChannel();
p.waitForStarted(-1);
以上版本的脚本都没有任何效果。
(使用pid忽略我的脚本的一种可能性是osascript可能正在使用窗口id,这可能与进程ID不同 - 我已经搜索了获取windows id的方法但是我找不到任何可以使用的内容在Qt内部。)
其他更新:
我创建了一个信号,并在启动后向调用者发送了“emit”,这样我也许可以做一些事情来隐藏调用者窗口。尝试最小化然后恢复调用者看起来很可怕,特别是由于动画。但它总比没有好......至少它可以通知用户发生了什么事情,并且,如果呼叫者被最大化并且底座被隐藏,则向呼叫者显示在后台可能有帮助......某事。 (虽然这不是真正的解决方案)
即使这种可怕的尝试也行不通。如果帮助已在运行,则最小化和恢复调用者窗口将导致后台帮助窗口瞬间可见,当然还原的调用者将显示在其上方。但是......如果助理第一次启动,那么后面就没有了! waitForStarted()已经是真的但是助手需要更长的时间才能显示....加载其帮助数据库可能需要很长时间?
这可能是为什么进程总是在后台开始的原因(不是后台进程,而是作为调用者窗口后面的窗口)?它没有足够快地显示自己,所以它没有得到焦点?如果这样的事情发生了,我该如何解决?
......我尝试添加一个计时器,然后调用上面的actionscript命令,我可以清楚地看到等待光标,而助理窗口显示在应用程序窗口后面 - 但是当动作脚本项目运行时没有看到效果 - 所以他们一定都错了。
令人难以置信的沮丧!
似乎Windows中存在针对此问题的解决方案(链接一对,以获取创意):
(1) Bring to front window application managed with QProcess
(2) qt-assistant-how-to-maximize-help-window-when-qt-assistent-is-started-as-proces
但我还没有在Linux或Windows中看到这种奇怪的行为。它似乎只发生在OSX上,对于我的应用程序。由于流程行为取决于系统,我需要OSX的一些解决方案......请帮忙!