Russian Qt Forum

Qt => Общие вопросы => Тема начата: cresta от Февраль 25, 2009, 15:54



Название: QProcess::FailedToStart
Отправлено: cresta от Февраль 25, 2009, 15:54
Добрый день!

Процесс не стартует. Исполняемый файл в наличии, права доступа соблюдены.
Запуск вручную из консоли работает
Как определить причину незапуска процесса из приложения?

Qt4.2
mdv2008


Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 17:09
Былобы неплохо увидето код.


Для проверки, попробуй запустиьт через system:


system("path/to/your_app");


Название: Re: QProcess::FailedToStart
Отправлено: cresta от Февраль 25, 2009, 18:38
Код:
class SChecker : public QProcess{
    Q_OBJECT
    public :
        SChecker (QObject *parent=0);

        QString         procName, argList;
        QProcess      *p;

    private slots:
        void pilotStarted();
        void monitorStdout();
        void pilotExited();
        void pilotStateChanged(QProcess::ProcessState newState);
        void pilotError (QProcess::ProcessError error);

    signals:
        virtual void stateChanged (QProcess::ProcessState newState);
        virtual void readyReadStandardOutput ();
        virtual void error (QProcess::ProcessError error);
        void pilotReady();
   
};

SChecker::SChecker(QObject *parent)
    :QProcess(){

    QStringList arguments;
    arguments << "/";

    p = new QProcess ();
    connect( p, SIGNAL(started()), this, SLOT(pilotStarted()) );
    connect( p, SIGNAL(readyReadStandardOutput ()), this, SLOT(monitorStdout()) );
    connect( p, SIGNAL(error (QProcess::ProcessError)), this, SLOT(pilotError (QProcess::ProcessError)) );
    connect( p, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(pilotStateChanged(QProcess::ProcessState)) );

    p->start("/bin/df", arguments);    //так стартует, правда нет вывода в консоль
    p->start(this->procName, arguments);    //так не стартует, переменная procName почему-то пустая

    qDebug("PROCESS NAME : %s", this->procName.toLocal8Bit().constData()); //выводит пустую строку

}

void SChecker::monitorStdout(){
    QByteArray      output;

    qDebug("Ready");
    output = readAllStandardOutput ();
    qDebug() << output;

}

int main(int argc, char *argv[])
 {
    QApplication    app(argc, argv);
    MyWidget        widget;
    SChecker        *proc = new SChecker;

    proc->procName = "/bin/df";

     widget.show();
     return app.exec();
 }

В чем проблема? Почему если указать явно путь при старте процесса, то стартует, через паблик переменную - нет? Переменная proicName пустая...

И почему ничего нет в stdout?




Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 18:52
Цитировать
так не стартует, переменная procName почему-то пустая

А ты внимательно посомтри на функцию main. Сначало создается объект SChecker, а потом происходит установка значения procName. Запуск процесса происходит в конструкторе SChecker.

Ещё есть вопрос, зачен наследоваться от QProcess и при этом ещё создавать член класса QProcess (p) ?


Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 18:55
И почему ничего нет в stdout?

Код
C++ (Qt)
void SChecker::monitorStdout(){
   QByteArray      output;
 
   qDebug("Ready");
   output = p->readAllStandardOutput ();   // <-----
   qDebug() << output;
 
}


Название: Re: QProcess::FailedToStart
Отправлено: cresta от Февраль 25, 2009, 20:20
А, понятно. Значит передавать через стек имя процесса в конструктор.
Либо стартовать процесс не в конструкторе и передавать имя через отдельную функцию.

Сейчас сделал так: изменил декларацию класса

Код:
class SChecker : public QProcess{
    Q_OBJECT
    public :
        SChecker (QObject *parent=0, QString procName=0);

        QProcess        *p;

    private slots:
        void pilotStarted();
        void monitorStdout();
        void pilotExited();
        void pilotStateChanged(QProcess::ProcessState newState);
        void pilotError (QProcess::ProcessError error);

    signals:
        virtual void stateChanged (QProcess::ProcessState newState);
        virtual void readyReadStandardOutput ();
        virtual void error (QProcess::ProcessError error);
        void pilotReady();
   
};

SChecker::SChecker(QObject *parent, QString procName)
    :QProcess(){

    QStringList arguments;
    arguments << "/";

    p = new QProcess ();
    connect( p, SIGNAL(started()), this, SLOT(pilotStarted()) );
    connect( p, SIGNAL(readyReadStandardOutput ()), this, SLOT(monitorStdout()) );
    connect( p, SIGNAL(error (QProcess::ProcessError)), this, SLOT(pilotError (QProcess::ProcessError)) );
    connect( p, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(pilotStateChanged(QProcess::ProcessState)) );

    p->start(procName, arguments);
    qDebug("PROCESS NAME : %s", procName.toLocal8Bit().constData());

}

void SChecker::monitorStdout(){
    QByteArray      output;

    qDebug("Ready");
    output = readAllStandardOutput ();
    qDebug() << output;
}

void SChecker::pilotStateChanged(ProcessState newState){
    qDebug("Process State code: %d", newState);
}

void SChecker::pilotError(ProcessError error){
    qDebug("Error code: %d", error);
}

 int main(int argc, char *argv[])
 {
    QApplication    app(argc, argv);
    MyWidget        widget;
    SChecker        *proc = new SChecker(0, "/bin/df");

    widget.show();
    return app.exec();
 }


По-прежнему результата нет, хотя имя исполняемого файла в порядке: в конструкторе выводится /bin/df
Чтобы контролировать визуально, стартанул калькулятор /bin/kcalc: сам калькулятор не появляется, хотя в слоте pilotStateChanged трижды изменяется состояние процесса: сначала приходит состояние 1(Starting), затем 2 (Running), затем 0 (NotRunning)
Слот pilotError молчит...

Всё-таки, почему калькулятора нет?


P.S.
О наследовании: иначе, чем сделано сейчас, у меня сигналы не доходят до слотов

P.P.S.

А что неправильно в этой строке:
output = p->readAllStandardOutput ();   // <-----
??


Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 20:22
P.S.
О наследовании: иначе, чем сделано сейчас, у меня сигналы не доходят до слотов

Для реализации сигналов слотов достаточно наследоваться от QObject:

Код
C++ (Qt)
class SChecker : public QObject{
   Q_OBJECT
...
};


Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 20:27
P.P.S.
А что неправильно в этой строке:
output = p->readAllStandardOutput ();   // <-----
??

У тебя было написано readAllStandardOutput(), я изменил на p->readAllStandardOutput (), см. свой конструктор:

Код
C++ (Qt)
SChecker::SChecker()
{
...
   p = new QProcess ();
...
}


Название: Re: QProcess::FailedToStart
Отправлено: BRE от Февраль 25, 2009, 20:34
Чтобы контролировать визуально, стартанул калькулятор /bin/kcalc: сам калькулятор не появляется, хотя в слоте pilotStateChanged трижды изменяется состояние процесса: сначала приходит состояние 1(Starting), затем 2 (Running), затем 0 (NotRunning)
Слот pilotError молчит...

Всё-таки, почему калькулятора нет?

А ты ему в аргументах передаешь "/", он запускается, пугается (выдает в консоль сообщение) и выходит.
Убери аргумент.


Название: Re: QProcess::FailedToStart
Отправлено: cresta от Февраль 25, 2009, 21:08
Да, действительно пугается :)
Только я пробовал передавать "" вместо "/", а надо было просто неинициализированный список передавать.

Сейчас почти все правильно, за исключением кодировки выводимой в stdout строки.
Ну с этим я сам попробую разобраться.

Цитировать
Для реализации сигналов слотов достаточно наследоваться от QObject:

В этом случае я получаю ошибки: ругается на то, что start, readAllStandardOutput и все прочие члены класса не являются членами класса QObject. Собственно, так оно и есть. Если эти члены задекларировать в своём .h, то тут уже другая ошибка: линкер спотыкается undefined reference to `SChecker::start(QString const&, QStringList const&)'

Как правильно это делается?


Название: Re: QProcess::FailedToStart
Отправлено: pastor от Февраль 25, 2009, 21:19
В этом случае я получаю ошибки: ругается на то, что start, readAllStandardOutput и все прочие члены класса не являются членами класса QObject. Собственно, так оно и есть.

Покажите код где ругается.


Как правильно это делается?

Все зависит от задачи. Если создаешь объект (proc) класса SChecker и далее с нима работаешь (proc-start(...), etc), то тогда наследуйся от QProcess, но тогда не нужен член класса QProcess *p.


Название: Re: QProcess::FailedToStart
Отправлено: cresta от Февраль 25, 2009, 22:37
Цитировать
Если создаешь объект (proc) класса SChecker и далее с нима работаешь (proc-start(...), etc), то тогда наследуйся от QProcess, но тогда не нужен член класса QProcess *p.

Понял. Вызывать proc->start в main,  а не p->start в конструкторе.

Ну собственно весь вопрос исчерпан.

Спасибо всем