문제

QT 문서화에 따르면 신호와 슬롯이 될 수 있습니다 direct, queued 그리고 auto.

또한 신호를 소유 한 객체와 다른 스레드에서 슬롯 Lives '를 소유 한 객체는 이러한 신호를 게시하는 것이 메시지를 게시하는 것과 같습니다.

불행히도, 문서는 'Lives'가 의지한다는 것을 명시하지 않으며 예제를 사용할 수 없습니다. 다음 코드를 시도했습니다.

main.h:

class CThread1 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        msleep( 200 );
        std::cout << "thread 1 started" << std::endl;
        MySignal();
        exec();
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

main.cpp:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & oThread2, SLOT( MySlot() ) );
    oThread1.start();
    oThread2.start();
    oThread1.wait();
    oThread2.wait();
    return a.exec();
}

출력은 다음과 같습니다.

thread 2 started
thread 1 started

MySlot() 호출되지 않았다 :(. 내가 뭘 잘못하고 있는가?

도움이 되었습니까?

해결책

코드에는 몇 가지 문제가 있습니다.

  • Evan의 말과 마찬가지로 Emit 키워드가 누락되었습니다
  • 모든 객체는 기본 스레드에 살고 있으며 실행 메소드의 코드 만 다른 스레드에 살고 있습니다. 즉, MySlot 슬롯이 기본 스레드에서 호출 될 것이며 그것이 원하는 것이 확실하지 않습니다.
  • 메인 이벤트 루프가 시작되지 않았기 때문에 슬롯이 호출되지 않습니다. 대기 전화 통화는 매우 오랜 시간이 지나면 타임 아웃 (아마도 그 전에 응용 프로그램을 죽일 것입니다). 그것이 당신이 원하는 것입니다. 어쨌든 그들은 실제로 당신의 코드에 사용하지 않습니다.

이 코드는 가장 효과가있을 가능성이 높으며 (테스트하지는 않았지만) 당신이 원하는 일을한다고 생각합니다.

class MyObject : public QObject
{
    Q_OBJECT
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

class CThread1 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 1 started" << std::endl;
        int i = 0;
        while(1)
        {
           msleep( 200 );
           i++;
           if(i==1000)
              emit MySignal();
        }
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    MyObject myObject;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & myObject, SLOT( MySlot() ) );
    oThread2.start();
    myObject.moveToThread(&oThread2)
    oThread1.start();
    return a.exec();
}

이제 myObject는 Thread2에 살게됩니다 (Movetothread 덕분).

MySignal은 Thread1에서 전송되어야합니다.

신호를 방출하는 데 이벤트 루프가 필요하지 않기 때문에 Thread1에는 이벤트 루프가 필요하지 않습니다. 이벤트 루프는 신호를 수신하기 위해 Thread2 (exec ()에 의해 lanched)에 필요합니다.

MySlot은 Thread2에서 호출됩니다.

다른 팁

QT 4.4+의 경우 QTHREAD 하위 클래스를하지 마십시오

AIUA의 대답은 좋지만 Qthread와 QT 4.6 또는 4.7의 몇 가지 문제를 지적하고 싶습니다.

이 기사는 다음을 요약합니다. http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

QT 부분에 대한 문서가 부족합니다

불행히도 문제는 문서에 대한 업데이트 부족에서 비롯됩니다. QT 4.4 이전에 Qthread는 기본 run () 구현이 없었으므로 Qthread를 서브 클래스를 사용해야했습니다.

QT 4.6 또는 4.7을 사용하고 있다면 거의 확실하게 ~ 아니다 서브 클래스 qthread.

Movetothread를 사용하십시오

작업자 스레드에서 슬롯을 실행하는 것의 핵심은 AIUA가 지적한대로 Movetothread 메소드를 사용하는 것입니다.

스레드 기능을 시작하려면 신호를 방출해야합니다.

emit operateCut(examId,examName_examTemplate[examName].studentIdRec,examName_examTemplate[examName].choiceRecA,examName_examTemplate[examName].choiceRecB,examName_examTemplate[examName].objectRecA,examName_examTemplate[examName].objectRecB);

이 신호에서 하나 이상의 인수를 추가 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top