2010-05-10 21 views
6

Mi primer ingenua en la actualización de mi barra de progreso fue la de incluir las siguientes líneas en mi bucle que está haciendo el procesamiento, haciendo algo como esto:QProgressBar no muestra el progreso?

while(data.hasMoreItems()) 
{ 
    doSomeProcessing(data.nextItem()) 

    //Added these lines but they don't do anything 
    ui->progressBar->setValue(numberProcessed++); 
    ui->progressBar->repaint(); 
} 

pensé añadiendo el repaint() haría que la pausa ejecución mientras se actualiza la GUI, pero aparentemente no es tan simple. Después de mirar las preguntas:

QProgressBar Error
Progress bar is not showing progress

parece que voy a tener que poner el procesamiento de datos en un hilo diferente y luego conectar una señal desde el subproceso de procesamiento de datos para el hilo GUI para actualizar la barra de progreso Soy bastante inexperto con interfaces gráficas e hilos y me preguntaba si alguien podría simplemente señalarme en la dirección correcta, es decir, qué clases de Qt debería estar buscando usar para esto. Supongo que necesito un objeto QThread pero he estado buscando en la documentación de QProgressBar pero no aparece el tema de enhebrar.

Respuesta

9

Como @rjh y @Georg han señalado, existen básicamente dos opciones diferentes: el procesamiento

  1. Fuerza de eventos utilizando QApplication::processEvents() O
  2. Crear una thread que emite señales que se pueden utilizar para actualizar la barra de progreso

Si está haciendo un procesamiento no trivial, le recomendaría mover el procesamiento a un hilo.

Lo más importante que debe saber sobre los hilos es que excepto el hilo de la GUI principal (que no inicia ni crea), nunca puede actualizar la GUI directamente desde dentro de un hilo.

El último parámetro de QObject::connect() es una enumeración Qt::ConnectionType que, de forma predeterminada, tiene en cuenta si hay hilos implicados.

Por lo tanto, usted debe ser capaz de crear una subclase sencilla de QThread que hace el procesamiento:

class DataProcessingThread : public QThread 
{ 

public: 
    void run(); 
signals: 
    void percentageComplete(int); 
}; 

void MyThread::run() 
{ 
    while(data.hasMoreItems()) 
    { 
     doSomeProcessing(data.nextItem()) 
     emit percentageCompleted(computePercentageCompleted()); 
    } 
} 

Y a continuación, en algún lugar de su código de interfaz gráfica de usuario:

DataProcessingThread dataProcessor(/*data*/); 
connect(dataProcessor, SIGNAL(percentageCompleted(int)), progressBar, SLOT(setValue(int)); 
dataProcessor.start(); 
1

Puede crear una subclase de QThread que emita una señal progressChanged, que se conecta al QProgressBar.

connect() hace las conexiones auto connections por defecto. Eso significa que el mecanismo de ranura de señal ya se encarga de los problemas de subprocesamiento para usted, por lo que no tiene que preocuparse por eso.

3

Debe llamar al QApplication::processEvents() periódicamente dentro de su bucle de procesamiento para que pueda manejar los eventos de IU.

Como dice Georg, Qt es un entorno multitarea cooperativo de un solo hilo. Usted obtiene el control total de su proceso hasta que lo renuncie voluntariamente con processEvents() - hasta que lo haga, Qt no puede actualizar los elementos de la interfaz de usuario, manejar solicitudes de HTTP asincrónicas, manejar entradas, o prácticamente cualquier otra cosa. Depende de ti asegurarte de que esas cosas obtengan un intervalo de tiempo mientras estás en un largo ciclo de procesamiento.

Cuestiones relacionadas