Мониторинг графического интерфейса Qt из класса QThread

Я пытаюсь запустить фоновый поток (qthread), который должен отслеживать флажок в графическом интерфейсе, и он не запускается! Он строится, но во время выполнения я получаю эту ошибку:

«Необработанное исключение по адресу 0x0120f494 в файле program.exe: 0xC0000005: место чтения нарушения прав доступа 0xcdcdce55».

и он ломается на линии «подключиться». Как лучше всего это сделать?

guiclass::guiclass(){
    thread *t = new thread();
}

thread::thread(){
     guiclass *c = new guiclass();
     connect(c->checkBox, SIGNAL(stateChanged(int)), this, SLOT(checked(int)));

     ....
     start work
     ....
}

bool thread::checked(int c){
     return(c==0);
}

void thread::run(){

    if(checked()){
        do stuff
    }
}

person JonnyCplusplus    schedule 08.06.2011    source источник
comment
где вы инициализируете c->checkBox? как вы относитесь к тому, что new guiclass звонит new thread звонит new guiclass звонит new thread звонит new guiclassзвонит new thread звонит new guiclass ...   -  person Mat    schedule 09.06.2011
comment
Ясно, что я не имею дело с потоками, вызывающими друг друга, похоже на мою проблему. Итак, как бы я мог контролировать guiclass, не создавая объект guiclass?   -  person JonnyCplusplus    schedule 09.06.2011


Ответы (1)


Очередь событий любого объекта QThread фактически обрабатывается запустившим его потоком, что довольно неинтуитивно. Обычное решение состоит в том, чтобы создать объект «обработчик» (производный от QObject), связать его с вашим рабочим потоком, вызвав moveToThread, а затем привязать сигнал флажка к слоту этого объекта.

Код выглядит примерно так:

class ObjectThatMonitorsCheckbox : public QObject
{
     Q_OBJECT
     // ...

public slots:
     void checkboxChecked(int checked);
}

В коде, который создает поток:

QThread myWorkerThread;

ObjectThatMonitorsCheckbox myHandlerObject;

myHandlerObject.moveToThread(&myworkerThread);
connect(c->checkBox, SIGNAL(stateChanged(int)), &myHandlerObject, 
    SLOT(checkboxChecked(int)));

myWorkerThread.start();

Один ключевой момент: не делайте подкласс QThread -- вся фактическая работа выполняется в вашем объекте-обработчике.

Надеюсь это поможет!

См. также: Qt: правильный способ публикации событий в QThread?

person Tony the Pony    schedule 08.06.2011