2012-03-25 5 views
1

У меня есть следующий код:Как использовать процесс (QProcess) в новом потоке (QThread)?

void Processmethod() 
{ 

    QDialog *ProcessMessage = new QDialog;  
    Ui::DialogProcessMessage Dialog;    
    Dialog.setupUi(ProcessMessage);    
    ProcessMessage->setModal(true); 
    ProcessMessage->setAttribute(Qt::WA_DeleteOnClose); 
    ProcessMessage->show(); 

    qApp->processEvents(); 

    processmethodONE(); 
    processmethodTWO(); 
    processmethodTHREE();     
} 

void processmethodONE() 
{ 
    QString ProcessCommand = "w8 " + blablubli";    

    Prozess.setWorkingDirectory(Path);   //QProcess "Prozess" is globaly defined 
    Prozess.setStandardOutputFile(Path);  //in my class 

    QThread* thread = new QThread; 
    Prozess.moveToThread(thread); 
    Prozess.start(ProcessCommand); 


while(!Prozess.waitForFinished(2000)) 
    { 
     std::cerr << "Process running " << std::endl; 
    } 

QProcess::ExitStatus Status = Prozess.exitStatus(); 

if (Status == 0) 
{ 
    std::cout << "File created!" << std::endl; 
} 
} 

В этом исходном коде я пытаюсь открыть всплывающее диалоговое окно, прежде чем начинают какие-то процессы. проблема в том, что диалог не доступен, но в диалоговом окне я хочу создать кнопку, чтобы прервать выполняемый метод. Как вы можете видеть, я попытался использовать QThread для запуска процесса (процессов) в другом потоке, но все же я не могу щелкнуть диалог. Кроме того, если я открываю приложение (GUI) с «application/x-executable» -file, содержимое диалоговых окон отсутствует при активации вышеуказанного метода. Как я могу исправить эти проблемы? Где я ошибаюсь? привет

+1

У меня есть несколько вопросов ... 1) Как вы называете 'Processmethod()'? 2) Почему вы чувствуете, что вам нужно создать QThread и переместить QProcess в него? А также, почему вы не начинаете новый QThread? 3) Используете ли вы этот глобальный QProcess для всех своих 'processmethodX()'? – jdi

+0

он не подходит с вопросом, но я бы предложил вам написать имена переменных в _lowerCamelCase_. Это очень читаемо. Однако я согласен с jdi, вам нужно больше информации для ответа. – jalone

+0

Обычно нет необходимости запускать QProcess в потоке, поскольку его API не блокирует, если вы не используете методы waitForStarted/Finished. –

ответ

2
void processmethodONE() 
{ 
    QThread* thread = new QThread; 
    Prozess.moveToThread(thread); 
    Prozess.start(ProcessComand); 

Здесь вы переместили QProcess в другой поток. Но тогда вы вызываете start() на нем. Это уже не потокобезопасно.

while(!Prozess.waitForFinished(2000)) 
{ 
    std::cerr << "Process running " << std::endl; 
} 

Это блокирует и делает использование нити бесполезной. Кроме того, он не является потокобезопасным.

Вы должны вместо того, чтобы не использовать темы, но:

  1. удалить waitForFinished() вызов
  2. Подключение готового() и ошибки() сигналы QProcess слотов, которые затем начинают следующий шаг, т.е. processMethodTWO.

Я также рекомендовал бы повторно использовать объекты QProcess и просто создать новый для каждого шага.

+0

Хорошо, я сначала попробую это. У меня уже есть для каждого процесса один другой объект QProcess - вот что я хотел сказать с первого комментария. – Streight

+0

Я попытался подключить сигнал finish() первого процесса «Prozess» со вторым методом «processmethodTWO()» со связью (Prozess, SIGNAL (законченный()), processmethodTWO(), (SLOT (start()))); , но я получаю ошибку «недопустимое использование выражения void». -> возможно, noob не работает :). – Streight

1

Хотя я до сих пор не в полной мере понять свой недавно обновленный пример кода, я чувствую, что это может быть ваш вопрос:

while(!Prozess.waitForFinished(2000)) 
    { 
     std::cerr << "Process running " << std::endl; 
    } 

Где бы вы действительно называют это в исходном коде блокируется во время ожидания Prozess заканчивать.

Используйте новый экземпляр QProcess для каждого из них и подключите их сигналы finished() к SLOT, которые будут вызваны, когда они будут завершены. Не ругайте их вручную и блокируйте. Это позволит полностью избавиться от QThreads.

+0

У меня есть один глобальный для каждого процесса, это означает «один QProcess Prozess для processmethodONE();', 'один QProcess Prozess2 для processmethodTWO();' ... '' метод waitForFinished(), который мне нужен, потому что процессам нужно некоторое время и предыдущий процесс всегда должен быть завершен до следующего запуска. – Streight

+0

Если это так, то вам нужно сделать другой подход. В вашем примере было показано, что все процессы могут работать одновременно. Если вам нужно, чтобы они работали по порядку, вы могли бы связать сигнал 'законченного()' одного с словом 'start()' следующего и так далее. – jdi

+0

Или вы можете просто создать один пользовательский QThread, который выполняет все ваши команды, используя синхронные системные вызовы с более низким уровнем C++, поскольку QProcess больше не является преимуществом. А затем просто используйте сигнал QThread finished(), чтобы сообщить, что все это сделано. – jdi