#c #macos #qt #cocoa
#c #macos #qt #cocoa
Вопрос:
Я пытаюсь запустить приложение с графическим интерфейсом с помощью QProcess, но по умолчанию оно неактивно:
qint64 pid = 0;
QProcess::startDetached(executable, args, wd, amp;pid); //The app is in background
Я пробовал activateWithOptions
, и это не помогает:
qint64 pid = 0;
QProcess::startDetached(executable, args, wd, amp;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, amp;pid);
QThread::msleep(2000);
NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:static_cast<pid_t>(pid)];
[app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; //The app is in foreground!
Но QThread::msleep(2000)
выглядит как грязный взлом и не собирается проходить проверку кода 🙂
Итак, мой вопрос: как запустить процесс с графическим интерфейсом и запустить его без взломов?
PS: Я знаю, что QProcess::startDetached("open", "-a " executable);
это может сработать, но это не позволяет указать рабочий каталог, поэтому мне это не подходит
UPD: Похоже, мне нужно подождать, пока приложение завершит запуск, и тогда я смогу его активировать.
Комментарии:
1. Что произойдет, если вы используете,
open -a script.sh
гдеscript.sh
находится скрипт bash, который затем запускает желаемый исполняемый файл? Сработает ли это? В противном случае вы могли бы захотеть посмотреть на,QTimer::singleShot
а неQThread::msleep(2000)
.2. @G.M., насколько я понимаю,
open
всегда использует путь к исполняемому файлу в качестве рабочего каталога. Таким образом, запуск его из script на самом деле ничего не меняет
Ответ №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());