2011-06-06 6 views
6

Sigo los ejemplos del Qt SDK, iniciando el temporizador en la QThread Subclase pero sigo recibiendo la advertencia y el subproceso nunca inicia el temporizador. Aquí está el código:Subprocesos de QT: Obtención de QObject :: startTimer: los temporizadores no se pueden iniciar desde otra advertencia de subproceso

NotificationThread::NotificationThread(QObject *parent) 
      :QThread(parent), 
      m_timerInterval(0) 
{ 
moveToThread(this); 
} 


NotificationThread::~NotificationThread() 
{ 
; 
} 

void NotificationThread::fire() 
{ 
    WRITELOG("A::fire called -- currentThread:" + QString::number((int)currentThread()->currentThreadId())); 
    QVector<StringPer>* batchVectorResult = new QVector<StringPer>(); 
    emit UpdateGroupNotifications(batchVectorResult); 

} 

void NotificationThread::run() 
{ 

     connect(&m_NotificationTimer, SIGNAL(timeout()), 
       this,SLOT(fire(),Qt::DirectConnection)); 

     WRITELOG("A::run() worker thread -- currentThread:" + QString::number((int)currentThread()->currentThreadId())); 
    //SetNotificationTimerFromConf(); 
    QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD)); 
    int interval = val.toInt(); 
    m_NotificationTimer.setInterval(interval); 
     m_NotificationTimer.start(); 

     QThread::exec(); 
} 


void NotificationThread::SetNotificationTimerFromConf() 
{ 
QVariant val(ConfigSettings::getInstance()->ReadFromSettingsReturnVariant(SETTINGS_KEY_NOTIFICATIONTHREAD)); 
int interval = val.toInt(); 
m_NotificationTimer.setInterval(interval); 
} 


void NotificationThread::UpdateNotificationTimerRT(int timerInterval) 
{ 
m_NotificationTimer.setInterval(m_timerInterval); 
} 


void NotificationThread::Execute(const QStringList batchReqList) 
{ 
QVector<QString>* batchVectorResult = new QVector<QString>(); 
start(); 
} 

inicio el hilo de la interfaz de usuario principal con Execute().

Respuesta

7

Si se agrega la línea

m_NotificationTimer.moveToThread(this); 

al comienzo de ejecutar() método de su cadena de comandos desde ese punto en su objeto de temporizador invocará la ranura conectada dentro de su subproceso.

Cuando crea el temporizador por primera vez, se ejecutará dentro de su hilo principal. Al moverlo a su propio subproceso como se indica arriba, el método moveToThread cambiará la afinidad del subproceso del objeto del temporizador.

10

El problema es que crea el temporizador implícitamente por el hilo principal cuando crea su objeto de hilo. Esto se debe a que su temporizador es miembro de su clase de subprocesos.

Cuando intenta iniciar el temporizador, lo hace en un subproceso diferente (en run()), no en el subproceso donde se creó el temporizador, que le da la advertencia.

Debe crear el temporizador en la secuencia donde desea ejecutarlo :. Cambie la declaración de m_notificationTimer en su clase NotificcationThread de

QTimer m_NotificationTimer; 

a

QTimer* m_NotificationTimer; 

y crear el temporizador en run() con

m_NotificationTimer = new QTimer(this); 
m_NotificationTimer->setInterval(interval); 
m_NotificationTimer->start(); 
+0

o simplemente utilizar una lista de inicialización: clase MiClase: QObject pública { Q_OBJECT públicos: MiClase(): m_thread (este) {} QTimer m_timer; } – nocnokneo

2

También vale la pena mencionar esta article

El ajuste más grande para mí fue entender que las discusiones en Qt se utilizan como interfaz, y realmente no están destinados a la subclasificación. Habiendo dicho eso, mantendría tu clase y el QThread real separados. Y luego simplemente use YourClass.moveToThread (& YourQtThread) para asegurarse de que sus señales y ranuras se procesen en esa secuencia.

+0

El enlace al artículo se movió a http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/ – hcc23

+0

Gracias por la información. Actualicé el enlace – Aki

Cuestiones relacionadas