2012-05-19 3 views
1

Qt를 배우고 있는데 Qt wiki의 Threads, Events 및 QObjects에 대해 읽었으며 while 조건에서 일부 작업을 처리하는 방법에 대한 위키 권장 사항을 따랐지만 특정 케이스. 다음은 현재 달성하고자하는 간단한 예입니다.매초마다 메서드를 실행하는 QTimer

class FooEvents : public FooWrapper { 

    public virtual serverTime(..) { std::cout << "Server time event\n"; } 
    public virtual connected(..) { std::cout << "Connected event\n"; } 
} 

class Foo : public QObject { 

private: 

    FooAPI *client; 

public: 


    Foo(FooEvents *ev, QObject *parent = 0) : client(new FooApi(ev)) { .. } 

private slots: 
    void processMessages() { 

     if (state is IDLE)    

      reqFooAPiServerTime(); 

     select(client->fd()+1, ...); 

     if (socket is ready for read) 

      client.onReceive(); 

    } 
public: 
    void connect(...) { 

     if (connection) { 

      QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(processMessages())); 
      timer.start(1000); // I don't get the output from FooEvents 

     } 

    } 

} 

이것은 매우 간단하지만 내 경우를 설명한다고 생각합니다. 왜 이것이 효과가 없으며이 대안을 처리해야하는 다른 대안이 있습니까?

편집 Thanks.s : processMessages()가 SLOT 아니기 때문에 processMessages는 매 초마다 호출되고 있지만 이벤트

+0

에 간단한 호출 타이머를 우리는 "이해하지 못하는 구성 할 수있는 당신이 그것을 지정하지 않으면 "작동하지 않습니다! – ScarCode

+0

processMessages()가 이벤트와 어떻게 관련되는지 볼 수 없습니다 (FooEvents?) –

+0

@FrankOsterfeld. 내가 사용하고있는 API의 일부입니다. API가 제공하는 모든 이벤트를 구현해야하며 API 메소드를 호출하면 FooWrapper를 통해 해당 이벤트가 시작됩니다. – sectorzz9

답변

2

여기에 timer이 선언되고 정의되어 있습니까?

국지적 인 지역이 Foo::connect() 인 경우 화재가 발생하기 전에 파괴됩니다. 아마도 그것은 단지 Foo 클래스의 멤버 객체 일 필요가있을 것입니다. 단지 보호 된 가상 timerEvent() 기능을 무시하고 그 타이머 이벤트를 받기 시작하는있는 QObject의 startTimer() 전화 -

또한 QObject 그것이 타이머에 자신의 간단한 인터페이스의 제공한다는 점에 유의하십시오. 대신 타이머 이벤트를 수신 할 수있는 슬롯을 갖는이 경우, 그들은 단지 오버라이드 (override) timerEvent() 기능에 종료됩니다 :

protected: 
    void timerEvent(QTimerEvent *event) { 
     processMessages(); 
    } 

public: 
    void connect(/* ... */) { 

      // ... 

      startTimer(1000); 
    } 
+0

감사합니다. 이로 인해 문제가 해결되었습니다. – sectorzz9

+0

해결책은 정확하지만 timerEvent()를 재정의하는 것은 좋지 않습니다. 대신 QTimer를 사용하면 코드를 훨씬 깔끔하게 정리할 수 있으며 타이머 관련 작업 (예 : 매개 변수 설정 및 제어)을위한 전용 인터페이스가됩니다. –

+0

Viktor : QTimer에는 여분의 QObject로 인한 오버 헤드가 있으며 추가 신호 슬롯 연결이 있습니다. 분명한 메모리 오버 헤드 외에도, 직접 (대기열에 넣지 않은) 신호 슬롯 연결 오버 헤드는 내 컴퓨터에서 두 개의 1000 자 QString을 연결하는 것과 동일하므로 거의 쉽지 않습니다. QBasicTimer를 timerId의 자리 표시 자로 사용하고 타이머의 활성 상태는 적절한 최적화입니다. 나는 개인적으로 QTimer를 단발적으로 사용하며 거의 사용하지 않는 편익을 위해 사용합니다. 어떤 것도 주기적으로 QBasicTimer를 통해 진행되며'QObject :: timerEvent()'에서 처리됩니다. –

1

이 작동하지 않습니다에서 출력을하지 않습니다.

So Declare processMessages() as a private slot and then try. 
+0

슬롯으로 정의됩니다. 나는 그것을 예제에 넣는 것을 잊어 버렸다. – sectorzz9

+0

그런 다음 내부 (연결) 차단 여부를 확인하십시오!. – ScarCode

+0

맞습니다. 편집 메시지에서 말했습니다. ProcessMessages는 매초마다 호출되지만 이벤트는 시작되지 않습니다. processMessages를 직접 호출하면 작동합니다. – sectorzz9

0

당신은 타이머도 슬롯을 선언하지 않습니다. ...

또 다른 가능성을 또한

connect(&timer, SIGNAL(timeout()), this, SLOT(processMessages())); 
timer.setInterval(1000); 
timer.start(); 

timer.start(1000);이 유효 할 것 :

class ... { 

    QTimer timer; 
    ... 
private slots: 
    void processMessages(); 
    ... 
}; 

는 그 다음 신호 슬롯 연결을 기억하고 타이머를 구성 : 헤더에서는 선언해야

다른 가능성은 각 Q_OBJECT 및 ove와 연관된 타이머를 사용하는 것입니다

class ... { 
    Q_OBJECT 
    ... 
protected: 
    void timerEvent(QTimerEvent *event); 
    ... 
}; 

그런 다음이 같은 타이머 이벤트 구현해야합니다 : (가) timerEvent RLOAD

void MyClass::timerEvent(QTimerEvent *event) { 
    processMessages(); 
} 

을 그리고 당신은 startTimer(1000);

관련 문제