2011-04-23 3 views
2

I는 다음과 같습니다 EncodeThread라는 사용자 지정있는 QObject 클래스를 만들었습니다QThread는 사용하기 전에 실행/종료하지 않습니다.

으로 분명있을 수 있습니다,이 클래스는 외부 라이브러리를 사용하여 비디오를 인코딩하는 데 사용됩니다
class EncodeThread : public QObject { 
    Q_OBJECT 

public: 
    void set(SWSL::Video* v, QStringList f, QDir vDir); 
    void run(); 

public slots: 
    void encode(); 

signals: 
    void encodeProgress(int i); 

private: 
    SWSL::Video* video; 
    QStringList files; 
    QDir videoDir; 
}; 

. 그것은 분명 작동하지 않는 비록 인코딩()는 실행 실제 인코딩 루틴,()는 내가 문제 해결하면서 추가 기능을 포함

void EncodeThread::run() { 
    if (currentThread() != this) { 
     // caller is in different thread. 
     QMetaObject::invokeMethod(this, "encode", Qt::QueuedConnection); 
    } 
    else { 
     encode(); 
    } 
} 

난에 QThread과 moveToThread() 함수를 사용할 때 문제가 EncodeThread 인스턴스, 즉 아무 일도 일어나지 않는 것 같습니다. 데이터는 기록되지 않고 인스턴스는 인코딩 된 파일을 디스크에 저장해야하는 신호를 방출하지 않습니다.

encThread.set(video, files, videoDir); 
connect(&encThread, SIGNAL(encodeProgress(int)), cookVideoProgress, SLOT(setValue(int))); 
    connect(&encThread, SIGNAL(finished()), this, SLOT(videoCookEnd())); 
    connect(this, SIGNAL(videoEncode()), &encThread, SLOT(encode())); 
encThread.moveToThread(&thread); 
    thread.start(); 

위의 내용은 전체 설정이 시작되는 방법입니다. EncThread 및 스레드 변수는 MainWindow 클래스에서 선언됩니다. 신호를 사용하는 주 스레드에서 encode()를 호출하고 QMetaObject를 호출하지 못한 후에 EncodeThread 호출 encode()의 set() 함수가 실패했습니다.

네이티브 Windows 및 Linux 스레드뿐만 아니라 다양한 크로스 플랫폼 구현의 스레드를 사용하여 스레딩에 익숙하지는 않지만 QThread는 실제로 나를 당황하게합니다. 모든 제안은 환영보다 더 많습니다 :)

+0

언제'videoEncode() '신호가 방출됩니까? –

+1

원래 스레드를 시작한 직후 videoEncode() 신호가 방출되었지만 현재 문제에 비해 동작이 변경되지 않았습니다. – MayaPosch

답변

1

아마 당신에게 어떤 도움이 될지 모르지만, 여기에 EncoderThread 클래스를 작동시키는 약간의 데모 프로그램이 있습니다. 아마도 당신의 디자인 (당신의 질문은 단지 조각이라는 것)과 잘 맞지 않지만, 자신의 스레드에서 객체 인스턴스를 실행하고 신호/슬롯을 통해 서로 다른 스레드에서 2 개의 객체를 연결하여 통신 할 수 있음을 보여줍니다 :

#include <stdio.h> 
#include <QObject> 
#include <QThread> 
#include <QtCore/QCoreApplication> 

// QSleeper is just a toy utility class that makes the 
// protected QThread::sleep() family of functions 
// publicly accessible. It's only use is for demo 
// programs like this 
class Sleeper : QThread 
{ 
public: 
    static void sleep(unsigned long secs) { QThread::sleep(secs); } 
    static void msleep(unsigned long msecs) { QThread::msleep(msecs); } 
    static void usleep(unsigned long usecs) { QThread::usleep(usecs); } 

}; 


// an Encoder class that maintains itself on is own thread 
class EncodeThread : public QObject { 
    Q_OBJECT 

public: 
    EncodeThread(); 

public slots: 
    void encode(); 

signals: 
    void encodeProgress(int i); 
    void finished(); 

private: 
    QThread myThread; 
}; 

EncodeThread::EncodeThread() { 
    moveToThread(&myThread); 
    myThread.start(); 
} 


void EncodeThread::encode() 
{ 
    printf("EncodeThread::encode() on thread %u\n", (unsigned int) QThread::currentThreadId()); 

    for (int i = 0; i < 6; ++i) { 
     // encode for 1 second or so 
     printf("EncodeThread::encode() working on thread %u\n", (unsigned int) QThread::currentThreadId()); 
     Sleeper::sleep(1); 
     emit encodeProgress(i); 
    } 

    emit finished(); 
    printf("EncodeThread::encode() - done\n"); 
} 




// a controller to manage and monitor an EncoderThread instance 
class VideoEncoderController : public QObject 
{ 
    Q_OBJECT 
public: 
    void start(); 

public slots: 
    void setValue(int); 
    void encodingDone(); 

signals: 
    void encodingBegin(); 
}; 

void VideoEncoderController::start() 
{ 
    printf("VideoEncoderController::start() on thread %u\n", (unsigned int) QThread::currentThreadId()); 
    emit encodingBegin(); 
} 

void VideoEncoderController::setValue(int x) 
{ 
    printf("VideoEncoderController::setValue(int %d) on thread %u\n", x, (unsigned int) QThread::currentThreadId()); 
} 

void VideoEncoderController::encodingDone() 
{ 
    printf("VideoEncoderController::encodingDone() on thread %u\n", (unsigned int) QThread::currentThreadId()); 
} 




// a demo program that wires up a VideoEncoderController object to 
// an EncoderThread 
int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    EncodeThread encThread; 
    VideoEncoderController controller; 

    QObject::connect(&encThread, SIGNAL(encodeProgress(int)), &controller, SLOT(setValue(int))); 
    QObject::connect(&encThread, SIGNAL(finished()), &controller, SLOT(encodingDone())); 
    QObject::connect(&controller, SIGNAL(encodingBegin()), &encThread, SLOT(encode())); 

    printf("hello world on thread %u\n", (unsigned int) QThread::currentThreadId()); 

    controller.start(); 

    return a.exec(); 
} 



#include "main.moc" 
0

이 아니라 QObject을 파생해야합니다. run() 메서드는 추상 메서드 인 QThread입니다.

+1

네, 그 사실을 알고 있습니다 ... 저는 사용자 정의 QObject의 moveToThread() 함수를 사용하여 인스턴스를 QThread 인스턴스로 이동 시켰습니다. 함수를 run()이라고도 부르는 것은 단순한 우연의 일치입니다. – MayaPosch

관련 문제