2015-08-27 9 views
0


Использование цикла While для проверки состояния и использования таймера, если он не получает ответ от сервера в течение указанного времени.Закрытие клиентского приложения Qt в ожидании ответа от сервера

OS: Linux
SDK: QT 5,5

Описание:

Я implemenetd на стороне клиента и в коде есть время цикла, который бесступенчатой ​​проверяет некоторое условие (" проверка машины началась "). Это условие изменяется, когда оно получает сообщение от машинного сервера. Когда я реализовал цикл while, он застрял в нем и не вышел. Я уволил Вопрос в этом форуме, и кто-то был достаточно любезен, чтобы указать мне свою ошибку, и он предложил мне использовать QStateMachine, поскольку мой цикл while потребляет все мои ресурсы.

Так что, при поиске в googling больше о государственной машине, я столкнулся с QCoreApplication :: processEvents(). Когда я добавил его в свой код, все работает так, как ожидалось, но часть таймера еще раз. Теперь мой вопрос:

1) В чем разница между QStateMachine и QCoreApplication :: processEvents() &, который лучше.

2) Как правильно использовать QTimer, чтобы при условии, что условие в цикле while не станет истинным в оговоренном времени, просто таймаутом и пропустите цикл while.

void timerStart(QTimer* timer, int timeMillisecond) 
    { 
     timer = new QTimer(this); 
     connect(timer, SIGNAL(timeout()), this, SLOT(noRespFrmMachine())) ; 
     timer->start(timeMillisecond); 
    } 

    void timerStop(QTimer* timer) 
    { 
     if(timer) 
     { 
      timer->stop(); 
     } 
    } 

    void noRespFrmMachine() 
    { 
     vecCmd.clear(); 
    } 

    void prepareWriteToMachine() 
    { 
     // Some other code 
      // check if Machine has started we will get response in MainWindow and 
      // it will update isMachineStarted so we can check that 
      QTimer *timer ; 
      timerStart(timer, TIMEOUT_START); // IS THIS RIGHT?? 
      while(isMachineStarted() == false ) // getMachineRunning-> return isMachineStarted ?? 
      { 
       // do nothing wiat for machine server to send machine_started signal/msg 
     QCoreApplication::processEvents(); // added this one and my aplication is responsive and get correct result 

      } 
      if(isMachineStarted() == true) 
      { 
       // if we are here it mean timer has not expired & machine is runing 
       // now check for another command and execute 
       timerStop(timer); 
       while(vecCmd.size() > 0) 
       { 
        QString strTemp = returnFrontFrmVec(); 
        setStoreMsgFrmCliReq(strTemp); 
        reconnectToServer(); 
       } 
      } 
     } 
    } 
+1

Можете ли вы сделать свой isMachineStarted() в сигнал, который испускается при запуске вещи? Таким образом, не нужно будет ждать ожидание вызова processEvents(). – Archie

+0

если я использую сигнал, он пропустит условие цикла и выполнит другие команды, которые я не хочу, если он не будет выполнен. У меня нет проблемы с процессом. Событие все, что я хочу, чтобы разделить различие между событием Qprocess и машиной QState. – samprat

+0

Ну, QStateMachine - это реализация конечного автомата, в котором изменение состояния может быть вызвано сигналами. ProcessEvents() является частью механизмов цикла событий Qt, он отправляет ожидающие события в свои адресаты (слоты и обработчики событий). Таким образом, это две разные вещи и имеют мало общего, кроме как часть Qt-рамки. – Archie

ответ

0

Строка timerStop(timer); должна приводить к поломке сегментации. Функция timerStart не изменяет локальную переменную timer из prepareWriteToMachine(), так что переменная содержит неопределенный мусор.

Если вы хотите изменить внешнюю переменную timer в timerStart вы должны передать указатель на указатель на QTimer в этой функции:

void timerStart(QTimer**timer, int timeMillisecond) 
{ 
    *timer = new QTimer(this); 
    ... 
} 

Кстати, проверка if(timer) в timerStop() не имеет смысла в любом случае, поскольку timer никогда не устанавливается в ноль.

+0

@ Orest, "timerStart не меняет локальный таймер переменной prepareWriteToMachine". Мой вопрос в том, почему он изменился, поскольку я передаю varibale функции по ссылке? Почему вы считаете, что это ошибка сегментации? Я прошу разъяснить свои сомнения и изучить новую концепцию. – samprat

+0

@samprat, в настоящее время вы передаете переменную 'timer' в' timerStart' по значению. Таким образом, 'timer'' prepareWriteToMachine' не изменяется 'timerStart'. В результате переменная 'timer'' prepareWriteToMachine' никогда не инициализируется, что приводит к сбою. Действительно, вы можете передать его по ссылке. Для этого функция 'timerStart' должна быть определена символом амперсанда' void timerStart (QTimer * & timer, int timeMillisecond) '. В этом случае функция 'timerStart' будет работать непосредственно с внешней переменной' timer'. –