Pregunta

Tengo una clase, que es una abstracción de algún dispositivo.

class Device  
{  
public:  
  ...  
  void Start();  
  void Stop();  
  void MsgLoop();

signals:
  void sMsgArrived();
}  

Inicio () y detener () se llaman desde el hilo GUI. Start () comienza un nuevo hilo, que ejecuta msgloop (). Se parece a esto:

void MsgLoop()  
{
   forever {  
      if(SUCCESS == ReadMsg()) //synchronous, non-blocking
      {
        ProcessMsg(); //quite fast
        emit sMsgArrived(); //this signal is connected with a slot in GUI thread  
      }
   }
}

Cuando se llama a Stop (), el programa debe regresar de msgloop () y detener el hilo. ¿Cómo puedo implementar esto con Qthread sin subclasificarlo?

¿Fue útil?

Solución

En general, debe decidir quién será responsable de administrar el hilo. ¿Es el dispositivo o la ventana principal? O posiblemente algún administrador de dispositivos. En su caso, el dispositivo probablemente debería administrar su propio hilo, por lo que si no desea subclase, use la composición:

class Device : QObject
{
    Q_OBJECT
public:
    Device(QObject * parent = NULL);
    void Start();  
    void Stop();  

private slots:
    void MsgLoop();

signals:
    void sMsgArrived();

private:
    QThread thread;
    bool stopThread;
};


Device::Device(QObject * parent) : QObject(parent)
{
    moveToThread(&thread);
    connect(&thread, SIGNAL(started()), this, SLOT(MsgLoop()));
}

void Device::Start()
{
    stopThread = false;
    thread.start();
}

void Device::Stop()
{
    stopThread = true;
    thread.wait();      // if you want synchronous stop
}

void Device::MsgLoop()
{
  // your loop
  while(!stopThread)
    if(SUCCESS == ReadMsg())
    {
      ProcessMsg();
      emit sMsgArrived();
    }
  QThread::currentThread->quit();
}

Nota: la parada del hilo solo funcionará si ReadMsg Realmente no es bloqueo. Si luego decide cambiar al bloqueo de lectura (y eso probablemente sería apropiado para la mayoría de los casos), tendrá que descubrir otra forma de detener su hilo.

Otros consejos

Si miras esto Enlace Puede ver que es posible ejecutar un método en un hilo separado sin subclasificar un QTHREAD.

Sin embargo, lo que está preguntando es ejecutar un bucle de mensaje Siempre.

Si sigue el ejemplo dado, puede ejecutar su bucle sin subclasificar, pero el objeto Qthread nunca entrará en su propio bucle de mensajes Porque nunca volverá de tu ranura. Así que aquí hay un ejemplo, pero creo que sería un malo diseño

class Device : public QObject
{
Q_OBJECT

public:
Device(QObject* parent = 0);
~Device();

public Q_SLOTS:
  void MsgLoop();

};

QThread* thread = new QThread;
Device* device = new Device;

void Widget::onBtnStartClicked()
{

    device->moveToThread(thread);

    //This will call start method of Device
    connect(thread, SIGNAL(started()), device, SLOT(MsgLoop()));

    //This will start the event loop of thread
    thread->start();
}

void Widget::onBtnStopClicked()
{
 //Tells the thread to exit
 thread->exit(0);

}

Me temo que tienes que subclasear un QThread si quieres ejecutar un Siempre círculo.

En mi humilde opinión, no deberías. Las encuestas requieren estar en un bucle para siempre. Debe hacer esto en la función de ejecución de Qthread para que no haya forma de volver a implementar una función sin subclase primero. Incluso si intentara que se sienta por una sola vez con un solo temporizador de disparo, no lo recomiendo. Está mejor (así es como me gusta hacerlo) subclaseando qthread, llamando a Movetothread (), no llamar a Exec () y poner un bucle para siempre en ejecución. Para obtener un ejemplo de esta mirada al ejemplo del cliente de bloqueo de la fortuna de Qt. Si no llama a MovetothRead () en QTHREAD, el objeto QTHREAD todavía reside en el hilo principal de la GUI y ambos comparten el mismo bucle de eventos (que es malo al usar funciones de votación). Llamar a MovetothRead (QTHREAD) sin llamar a Exec () significa que QTHREAD no tendrá un bucle de eventos (que es bueno en su caso). Llamar a Exec () comenzaría su propio bucle de eventos pero no se usa para esquemas de votación y usted dejaría la función de ejecución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top