2014-04-26 6 views
1

일부 처리를 시작하는 트리거 함수를 호출해야하는 라이브러리를 사용하고 있습니다 (작업을 수행하는 스레드가 시작됨) immediatly를 반환합니다. 그런 다음 처리가 완료되면 신호가 방출됩니다.여러 QTimers 슬롯에 대기 호출

다른 매개 변수를 기반으로 주기적으로 수행해야합니다. 트리거 함수에 대한 다른 호출은 처리 중에 수행되어서는 안되기 때문에 어떤 식 으로든 큐 함수를 호출해야합니다. 지금까지 QEventLoop ("루프") 사용에 대해 생각했지만 운이 없었다.

이 코드 조각을보고하십시오 :

test::test() 
    { 
    connect(&timer, SIGNAL(timeout()), this, SLOT(timerSlot())); 
    connect(&timer2, SIGNAL(timeout()), this, SLOT(timer2Slot())); 
    connect(&library, SIGNAL(processingFinished()), &loop, SLOT(quit())); 

    timer.setInterval(2000); 
    timer.start(); 

    timer2.setInterval(4000); 
    timer2.start(); 
    } 

void test::timerSlot() 
    { 
    loop.exec(); 
    startProcessing(some_parameters); 
    } 

void test::timer2Slot() 
    { 
    loop.exec(); 
    startProcessing(some_other_parameters); 
    } 

문제입니다 처리하는 동안()를 호출 loop.exec 때 나는 메시지를 얻을 :

QEventLoop::exec: instance xxxxxx has already called exec() 

올바른 것입니다 무엇을 내가하려는 것을하는 방법?

미리 감사드립니다.

+0

매개 변수를 처리하는 동안 타이머 슬롯이 실행되지 않도록하려면 타이머 슬롯에서 신호 슬롯 연결을 끊고 처리가 끝나면 다시 연결하십시오. 그러나 처리 중에 발생하는 추가 타이머 이벤트를 "대기"하지 않습니다. 타이머 이벤트를 큐에 넣음으로써 달성하려는 것을 설명 할 수 있습니까? 처리가 완료되면 대기중인 모든 타이머 이벤트를 한 번에 실행 하시겠습니까? – deGoot

+0

Hello @deGoot와 답장을 보내 주셔서 감사합니다! 그것은 서버 - 클라이언트 모델입니다. 서버의 정보를 업데이트하기 위해 주기적으로 클라이언트를 폴링해야합니다. 폴링은 매 x 초마다 발생해야합니다. 나는 대기중인 모든 투표를 대기열에 넣는 것에는 관심이 없지만 최소한 두 번이 같은 시간에 발생하거나 이전 설문 조사가 진행되는 동안 적어도 첫 번째 완료 후에 마지막을 실행하고 싶습니다. 제안에 관해서 나는 타이머가 매 x 초마다 슬롯을 호출하고 중간에 모든 "일시 중지"를 더하기 때문에 폴링 기간에 상당한 왜곡을 일으킬 수 있다고 생각합니다. – Fracu

+1

그럴 경우 멤버 'bool m_is Processing' 변수를 사용하고'if (! m_isProcessing)'에서 타이머 코드를 감쌀 수 있습니다. 그리고 처리하는 동안 다른 타이머가 꺼 졌는지를 나타 내기 위해 멤버 변수를 가질 수도 있습니다. 그리고 처리가 완료되면 m_isProcessing을 재설정하고 다른 타이머의 작업을 시작하십시오. – deGoot

답변

1

하나의 간단한 해결책은, 예를 bool m_isProcessing 멤버 변수를 도입 일 경우에만 m_isProcess == false 처리를 시작한다 처리가 시작되면 true으로 설정하고 처리가 완료되면 false으로 재설정하십시오. test QObject 슬롯은 GUI/주 스레드에서 실행되므로 타이머 슬롯과 처리가 완료 될 때 실행할 슬롯 사이의 동기화에 대해 걱정할 필요가 없습니다.

처리 중에 발생하는 이벤트를 추적하려는 경우 동일한 방법을 사용할 수 있습니다. test 클래스에 멤버 변수를 도입하여 필요한 정보를 추적하십시오.

0

Qt::QueuedConnection을 찾고있는 것 같습니다.

Qt :: QueuedConnection 2 슬롯이 제어가 수신자 스레드의 이벤트 루프로 돌아갈 때 슬롯이 호출됩니다. 슬롯은 수신자의 스레드에서 실행됩니다. 당신은 작업자 스레드를 사용하여이 있지만, 이것은 거기에 수행하는 방법을 잘 알려진 만델 브로 예에 볼 수 있었다, 자세한 내용은

connect(&timer, SIGNAL(timeout()), SLOT(timerSlot()), Qt::QueuedConnection); 
connect(&timer2, SIGNAL(timeout()), SLOT(timer2Slot()), Qt::QueuedConnection); 

:

따라서, 다음과 같이 쓸 수

Mandelbrot Example

+0

안녕하세요. @ LaszloPapp 답변 해 주셔서 감사합니다. Qt :: QueuedConnection과 대기열에있는 연결을 만들지 만 루프 이전에 loop.exec()가 두 번 이상 호출됩니다. quit(). – Fracu

+0

@Fracu : 루프를 완전히 제거하십시오. – lpapp

+0

타이머에 의해 호출 된 슬롯은 라이브러리 처리를 트리거하는 것입니다. 그들은 즉시 끝납니다. 따라서 대기열은 그 이상으로 진행되어야합니다. 다음 슬롯 호출은 이전 처리가 완료된 후에 만 ​​허용되어야합니다 (라이브러리가 예제에서 루프를 종료하는 신호를 낼 때 발생 함). 그것의 비동기 처리. 나는 내부적으로 도서관이 실을 시작하고 있다고 믿는다. – Fracu