QFuture Class
template <typename T> class QFutureLa clase QFuture representa el resultado de un cálculo asíncrono. Más...
| Cabecera: | #include <QFuture> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core)target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
- Lista de todos los miembros, incluidos los heredados
- Miembros obsoletos
- QFuture es parte de la clase Threading Classes.
Nota: Todas las funciones de esta clase son thread-safe con las siguientes excepciones:
Tipos Públicos
| class | const_iterator |
| ConstIterator |
Funciones Públicas
| QFuture() | |
| QFuture(const QFuture<T> &other) | |
| ~QFuture() | |
| QFuture<T>::const_iterator | begin() const |
| void | cancel() |
(since 6.10) void | cancelChain() |
| QFuture<T>::const_iterator | constBegin() const |
| QFuture<T>::const_iterator | constEnd() const |
| QFuture<T>::const_iterator | end() const |
| bool | isCanceled() const |
| bool | isFinished() const |
| bool | isResultReadyAt(int index) const |
| bool | isRunning() const |
| bool | isStarted() const |
(since 6.0) bool | isSuspended() const |
(since 6.0) bool | isSuspending() const |
(since 6.0) bool | isValid() const |
(since 6.0) QFuture<T> | onCanceled(Function &&handler) |
(since 6.1) QFuture<T> | onCanceled(QObject *context, Function &&handler) |
(since 6.0) QFuture<T> | onFailed(Function &&handler) |
(since 6.1) QFuture<T> | onFailed(QObject *context, Function &&handler) |
| int | progressMaximum() const |
| int | progressMinimum() const |
| QString | progressText() const |
| int | progressValue() const |
| T | result() const |
| T | resultAt(int index) const |
| int | resultCount() const |
| QList<T> | results() const |
| void | resume() |
(since 6.0) void | setSuspended(bool suspend) |
(since 6.0) void | suspend() |
(since 6.0) T | takeResult() |
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> | then(Function &&function) |
(since 6.1) QFuture<QFuture<T>::ResultType<Function>> | then(QObject *context, Function &&function) |
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> | then(QThreadPool *pool, Function &&function) |
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> | then(QtFuture::Launch policy, Function &&function) |
(since 6.0) void | toggleSuspended() |
(since 6.4) QFuture<U> | unwrap() |
| void | waitForFinished() |
| QFuture<T> & | operator=(const QFuture<T> &other) |
Descripción detallada
QFuture permite sincronizar hilos contra uno o más resultados que estarán listos en un momento posterior. El resultado puede ser de cualquier tipo que tenga constructores default, copy y posiblemente move. Si un resultado no está disponible en el momento de llamar a las funciones result(), resultAt(), results() y takeResult(), QFuture esperará hasta que el resultado esté disponible. Puede utilizar la función isResultReadyAt() para determinar si un resultado está disponible o no. Para los objetos QFuture que informan de más de un resultado, la función resultCount() devuelve el número de resultados continuos. Esto significa que siempre es seguro iterar a través de los resultados desde 0 hasta resultCount(). takeResult() invalida un futuro, y cualquier intento posterior de acceder a resultado o resultados del futuro conduce a un comportamiento indefinido. isValid() indica si se puede acceder a los resultados.
QFuture proporciona un iterador estilo Java (QFutureIterator) y un iterador estilo STL (QFuture::const_iterator). Utilizar estos iteradores es otra forma de acceder a los resultados en el futuro.
Si el resultado de un cálculo asíncrono necesita ser pasado a otro, QFuture proporciona una forma conveniente de encadenar múltiples cálculos secuenciales utilizando then(). onCanceled() puede usarse para añadir un manejador a ser llamado si el QFuture es cancelado. Adicionalmente, onFailed() puede usarse para manejar cualquier fallo que ocurra en la cadena. Tenga en cuenta que QFuture se basa en excepciones para el manejo de errores. Si el uso de excepciones no es una opción, aún puede indicar el estado de error de QFuture, haciendo que el tipo de error forme parte del tipo QFuture. Por ejemplo, puede utilizar std::variant, std::any o similares para mantener el resultado o el fallo o hacer su tipo personalizado.
El siguiente ejemplo demuestra como el manejo de errores puede hacerse sin usar excepciones. Digamos que queremos enviar una petición de red para obtener un archivo grande de una ubicación de red. Luego queremos escribirlo en el sistema de archivos y devolver su ubicación en caso de éxito. Ambas operaciones pueden fallar con diferentes errores. Por lo tanto, utilizamos std::variant para guardar el resultado o el error:
using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>; enum class IOError { FailedToRead, FailedToWrite }; using IOResult = std::variant<QString, IOError>;
Y combinamos las dos operaciones usando then():
QFuture<IOResult> future = QtConcurrent::run([url] { //... return NetworkReply(QNetworkReply::TimeoutError); }).then([](NetworkReply reply) { if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply)) return IOResult(IOError::FailedToRead); auto data = std::get_if<QByteArray>(&reply); // try to write *data and return IOError::FailedToWrite on failure //... }); auto result = future.result(); if (auto filePath = std::get_if<QString>(&result)) { // do something with *filePath } else { // process the error }
Es posible encadenar múltiples continuaciones y manejadores en cualquier orden. Por ejemplo:
QFuture<int> testFuture = someIntFuture; auto resultFuture = testFuture.then([](int res) { // Block 1 }).onCanceled([] { // Block 2 }).onFailed([] { // Block 3 }).then([] { // Block 4 }).onFailed([] { // Block 5 }).onCanceled([] { // Block 6 });
Dependiendo del estado de testFuture (cancelado, tiene excepción o tiene resultado), se llamará al siguiente onCanceled(), onFailed() o then(). Así, si testFuture se cumple con éxito, se llamará a Block 1. Si también se cumple con éxito, se llamará al siguiente then() (Block 4). Si testFuture se cancela o falla con una excepción, se llamará a Block 2 o Block 3 respectivamente. El siguiente then() será llamado después, y la historia se repite.
Nota: Si Block 2 es invocado y lanza una excepción, el siguiente onFailed() (Block 3) se encargará de ello. Si se invirtiera el orden de onFailed() y onCanceled(), el estado de excepción se propagaría a las siguientes continuaciones y finalmente se atraparía en Block 5.
En el siguiente ejemplo se elimina el primer onCanceled() (Block 2):
QFuture<int> testFuture = someIntFuture; auto resultFuture = testFuture.then([](int res) { // Block 1 }).onFailed([] { // Block 3 }).then([] { // Block 4 }).onFailed([] { // Block 5 }).onCanceled([] { // Block 6 });
Si testFuture se cancela, su estado se propaga al siguiente then(), que también se cancelará. Así que en este caso se llamará a Block 6.
El futuro sólo puede tener una continuación. Considera el siguiente ejemplo:
QPromise<int> p; QFuture<int> f1 = p.future(); f1.then([](int) { qDebug("first"); }); QFuture<int> f2 = p.future(); f2.then([](int) { qDebug("second"); }); p.start(); p.addResult(42); p.finish();
En este caso f1 y f2 son efectivamente el mismo objeto QFuture, ya que comparten el mismo estado interno. Como resultado, la llamada a then en f2 sobrescribirá la continuación especificada para f1. Por lo tanto, sólo se imprimirá "second" cuando se ejecute este código.
QFuture también ofrece formas de interactuar con un cálculo en ejecución. Por ejemplo, la computación puede ser cancelada con la función cancel(). Para suspender o reanudar el cálculo, utilice la función setSuspended() o una de las funciones de conveniencia suspend(), resume(), o toggleSuspended(). Ten en cuenta que no todos los cálculos asíncronos en ejecución pueden cancelarse o suspenderse. Por ejemplo, el futuro devuelto por QtConcurrent::run() no puede cancelarse, pero el futuro devuelto por QtConcurrent::mappedReduced() sí.
Las funciones progressValue(), progressMinimum(), progressMaximum() y progressText() proporcionan información sobre el progreso. La función waitForFinished() hace que el subproceso de llamada se bloquee y espere a que finalice el cálculo, asegurándose de que todos los resultados estén disponibles.
El estado del cálculo representado por un QFuture puede consultarse mediante las funciones isCanceled(), isStarted(), isFinished(), isRunning(), isSuspending() o isSuspended().
QFuture<void> está especializado para no contener ninguna de las funciones de obtención de resultados. Cualquier QFuture<T> puede ser asignado o copiado en un QFuture<void> también. Esto es útil si sólo se necesita información de estado o progreso - no los datos de resultado reales.
Para interactuar con tareas en ejecución utilizando señales y ranuras, utilice QFutureWatcher.
También puede utilizar QtFuture::connect() para conectar señales a un objeto QFuture que se resolverá cuando se emita una señal. Esto permite trabajar con señales como con objetos QFuture. Por ejemplo, si se combina con then(), se pueden adjuntar múltiples continuaciones a una señal, que se invocan en el mismo hilo o en un nuevo hilo.
Las funciones QtFuture::whenAll() y QtFuture::whenAny() pueden utilizarse para combinar varios futuros y realizar un seguimiento de cuándo se completa el último o el primero de ellos.
Se puede crear un objeto QFuture listo con un valor o un objeto QFuture con una excepción utilizando las funciones de conveniencia QtFuture::makeReadyVoidFuture(), QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture() y QtFuture::makeExceptionalFuture().
Nota: Algunas APIs (ver QFuture::then() o varias sobrecargas del método QtConcurrent ) permiten programar el cálculo a un pool de hilos específico. Sin embargo, QFuture implementa un algoritmo de robo de trabajo para evitar bloqueos y optimizar el uso de hilos. Como resultado, los cálculos pueden ejecutarse directamente en el subproceso que solicita el resultado de QFuture.
Nota: Para iniciar un cálculo y almacenar los resultados en un QFuture, utilice QPromise o una de las APIs del framework Qt Concurrent del framework.
Véase también QPromise, QtFuture::connect(), QtFuture::makeReadyVoidFuture(), QtFuture::makeReadyValueFuture(), QtFuture::makeReadyRangeFuture(), QtFuture::makeExceptionalFuture(), QFutureWatcher, y Qt Concurrent.
Documentación de tipos de miembros
QFuture::ConstIterator
Sinónimo de estilo Qt para QFuture::const_iterator.
Documentación de funciones miembro
QFuture::QFuture()
Construye un futuro vacío y cancelado.
QFuture::QFuture(const QFuture<T> &other)
Construye una copia de other.
Véase también operator=().
QFuture::~QFuture()
Destruye el futuro.
Tenga en cuenta que esto no espera ni cancela el cálculo asíncrono. Utilice waitForFinished() o QFutureSynchronizer cuando necesite asegurarse de que el cálculo se completa antes de que se destruya el futuro.
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::begin() const
Devuelve un iterador const de estilo STL que apunta al primer resultado en el futuro.
Véase también constBegin() y end().
void QFuture::cancel()
Cancela el cálculo asíncrono representado por este futuro. Tenga en cuenta que la cancelación es asíncrona. Utilice waitForFinished() después de llamar a cancel() cuando necesite una cancelación sincrónica.
Todavía se puede acceder a los resultados actualmente disponibles en un futuro cancelado, pero los nuevos resultados no estarán disponibles después de llamar a esta función. Cualquier objeto QFutureWatcher que esté observando este futuro no entregará señales de progreso y de resultado listo en un futuro cancelado.
Ten en cuenta que no todos los cálculos asíncronos en ejecución pueden cancelarse. Por ejemplo, el futuro devuelto por QtConcurrent::run() no puede cancelarse; pero el futuro devuelto por QtConcurrent::mappedReduced() sí.
Véase también cancelChain().
[since 6.10] void QFuture::cancelChain()
Cancela toda la cadena de continuación. Todos los futuros ya finalizados permanecen sin cambios y sus resultados siguen disponibles. Se cancela cada continuación pendiente y se llama a su manejador onCanceled(), si existe en la cadena de continuación.
auto f = QtConcurrent::run([] {/*...*/}) .then([]{ // Then 1 }) .then([]{ // Then 2 }) .onCanceled([]{ // OnCanceled 1 }) .then([]{ // Then 3 }) .then([]{ // Then 4 }) .onCanceled([]{ // OnCanceled 2 }); //... f.cancelChain();
En el ejemplo, si la cadena se cancela antes de que se ejecute la continuación Then 2, se invocarán los manejadores de cancelación OnCanceled 1 y OnCanceled 2.
Si la cadena se cancela después de Then 2, pero antes de Then 4, sólo se invocará a OnCanceled 2.
Nota: Cuando se llama a un futuro ya finalizado, este método no tiene ningún efecto. Se recomienda utilizarlo sobre el objeto QFuture que representa toda la cadena de continuación, como se muestra en el ejemplo anterior.
Si alguna de las continuaciones de la cadena ejecuta un cálculo asíncrono y devuelve un QFuture que lo representa, la llamada a cancelChain() no se propagará a dicho cálculo anidado una vez iniciado. La razón de ello es que el futuro estará disponible en la cadena de continuación sólo cuando se cumpla el futuro externo, pero la cancelación puede ocurrir cuando tanto un futuro externo como uno anidado están todavía esperando a que terminen sus cómputos. En estos casos, el futuro anidado debe capturarse y cancelarse explícitamente.
QFuture<void> nested; auto f = createFuture() .then([&]{ nested = runNestedComputation(); // do some other work return nested; }) .unwrap() .then([]{ // other continuation }) .onCanceled([]{ // handle cancellation }); //... f.cancelChain(); nested.cancel();
En este ejemplo, si runNestedComputation() ya está en curso, sólo puede cancelarse llamando a nested.cancel().
Esta función se introdujo en Qt 6.10.
Véase también cancel().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constBegin() const
Devuelve un iterador const de estilo STL que apunta al primer resultado en el futuro.
Véase también begin() y constEnd().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constEnd() const
Devuelve un iterador const de estilo STL que apunta al resultado imaginario después del último resultado en el futuro.
Véase también constBegin() y end().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::end() const
Devuelve un iterador const de estilo STL que apunta al resultado imaginario después del último resultado en el futuro.
Véase también begin() y constEnd().
bool QFuture::isCanceled() const
Devuelve true si el cálculo asíncrono se ha cancelado con la función cancel(); en caso contrario devuelve false.
Tenga en cuenta que el cálculo puede seguir en curso aunque esta función devuelva true. Véase cancel() para más detalles.
bool QFuture::isFinished() const
Devuelve true si el cálculo asíncrono representado por este futuro ha finalizado; en caso contrario, devuelve false.
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> bool QFuture::isResultReadyAt(int index) const
Devuelve true si el resultado en index está disponible inmediatamente; en caso contrario devuelve false.
Nota: Llamar a esta función conduce a un comportamiento indefinido si isValid() devuelve false para este QFuture. Si este QFuture aún no se ha iniciado, llame a waitForFinished() antes de llamar a esta función para evitar un comportamiento indefinido.
Véase también resultAt(), resultCount(), y takeResult().
bool QFuture::isRunning() const
Devuelve true si el cálculo asíncrono representado por este futuro se está ejecutando actualmente; en caso contrario, devuelve false.
bool QFuture::isStarted() const
Devuelve true si se ha iniciado el cálculo asíncrono representado por este futuro; en caso contrario, devuelve false.
[since 6.0] bool QFuture::isSuspended() const
Devuelve true si se ha solicitado una suspensión del cómputo asíncrono, y está en efecto, lo que significa que no se esperan más resultados o cambios de progreso.
Esta función se introdujo en Qt 6.0.
Véase también setSuspended(), toggleSuspended(), y isSuspending().
[since 6.0] bool QFuture::isSuspending() const
Devuelve true si el cálculo asíncrono se ha suspendido con la función suspend(), pero el trabajo aún no se ha suspendido y el cálculo sigue en curso. En caso contrario, devuelve false.
Para comprobar si la suspensión está realmente en efecto, utilice isSuspended() en su lugar.
Esta función se introdujo en Qt 6.0.
Véase también setSuspended(), toggleSuspended() y isSuspended().
[since 6.0] bool QFuture::isValid() const
Devuelve true si se puede acceder o tomar un resultado o resultados de este objeto QFuture. Devuelve false si el QPromise relacionado aún no ha comenzado o el resultado ya ha sido recogido del futuro.
Nota: El valor de retorno de esta función sólo implica si se puede consumir el resultado del futuro, no si está listo. Esta función devolverá true cuando el QPromise relacionado se haya iniciado, pero el resultado aún no esté listo. Para comprobar si está listo, llame a isResultReadyAt() o isFinished().
Esta función se introdujo en Qt 6.0.
Véase también takeResult(), result(), results(), resultAt(), isFinished(), y isResultReadyAt().
[since 6.0] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(Function &&handler)
Añade una cancelación handler a este futuro. El futuro devuelto se comporta exactamente como este futuro (tiene el mismo estado y resultado) a menos que este futuro sea cancelado. El handler es un callable que no toma argumentos y devuelve un valor del tipo empaquetado por este futuro. Tras la cancelación, el futuro devuelto empaqueta el valor devuelto por handler.
Si se adjunta antes de la cancelación, handler se invocará en el mismo hilo que informa del futuro como finalizado tras la cancelación. Si el manejador se adjunta después de que este futuro ya ha sido cancelado, será invocado inmediatamente en el hilo que ejecuta onCanceled(). Por lo tanto, el manejador no siempre puede hacer suposiciones sobre en qué hilo se ejecutará. Utiliza la sobrecarga que toma un objeto de contexto si quieres controlar en qué hilo se invoca el manejador.
El siguiente ejemplo muestra cómo adjuntar un controlador de cancelación:
QFuture<int> testFuture /*...*/; auto resultFuture = testFuture.then([](int res) { // Block 1 //... return 1; }).then([](int res) { // Block 2 //... return 2; }).onCanceled([] { // Block 3 //... return -1; });
Si testFuture es cancelado, Block 3 será llamado y resultFuture tendrá -1 como resultado. A diferencia de testFuture, no estará en un estado Canceled. Esto significa que puedes obtener su resultado, adjuntarle countinuaciones, etc.
También ten en cuenta que puedes cancelar la cadena de continuaciones mientras se están ejecutando a través del futuro que inició la cadena. Digamos que testFuture.cancel() fue llamada mientras Block 1 ya se estaba ejecutando. La siguiente continuación detectará que se solicitó la cancelación, por lo que Block 2 se saltará, y se llamará al manejador de cancelaciones (Block 3).
Nota: Este método devuelve un nuevo QFuture que representa el resultado de la cadena de continuación. La cancelación del propio QFuture resultante no invocará al manejador de cancelación de la cadena que condujo a él. Esto significa que si llamas a resultFuture.cancel(), Block 3 no será llamado: porque resultFuture es el futuro que resulta de adjuntar el manejador de cancelación a testFuture, ningún manejador de cancelación ha sido adjuntado a resultFuture mismo. Sólo la cancelación de testFuture o los futuros devueltos por las continuaciones adjuntas antes de la llamada a onCancelled() pueden activar Block 3.
Esta función se introdujo en Qt 6.0.
Véase también then() y onFailed().
[since 6.1] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(QObject *context, Function &&handler)
Adjunta una cancelación handler a este futuro, para ser llamado cuando el futuro es cancelado. El handler es un callable que no toma argumentos. Será invocado en el hilo del objeto context. Esto puede ser útil si la cancelación necesita ser manejada en un hilo específico.
Si context se destruye antes de que la cadena haya terminado, el futuro se cancela. Véase then() para más detalles.
Nota: Al llamar a este método, debe garantizarse que context permanece vivo durante la configuración de la cadena.
Véase la documentación de la otra sobrecarga para más detalles sobre handler.
Esta es una función sobrecargada.
Esta función se introdujo en Qt 6.1.
Véase también then() y onFailed().
[since 6.0] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(Function &&handler)
Adjunta un manejador de fallos a este futuro, para manejar cualquier excepción. El futuro devuelto se comporta exactamente como este futuro (tiene el mismo estado y resultado) a menos que este futuro falle con una excepción.
handler es un callable que no toma argumento o toma un argumento, para filtrar por tipos de error específicos, similar a la sentencia catch. Devuelve un valor del tipo empaquetado por este futuro. Tras el fallo, el futuro devuelto empaqueta el valor devuelto por handler.
El manejador sólo se invocará si se produce una excepción. Si la excepción es lanzada después de que este manejador es adjuntado, el manejador es ejecutado en el hilo que reporta el futuro como terminado como resultado de la excepción. Si el manejador se adjunta después de que este futuro ya ha fallado, será invocado inmediatamente, en el hilo que ejecuta onFailed(). Por lo tanto, el manejador no siempre puede hacer suposiciones sobre en qué hilo se ejecutará. Utiliza la sobrecarga que toma un objeto de contexto si quieres controlar en qué hilo se invoca el manejador.
El siguiente ejemplo muestra cómo adjuntar un controlador de fallos:
QFuture<int> future = someIntFuture; auto resultFuture = future.then([](int res) { //... throw Error(); //... return res; }).onFailed([](const Error &e) { // Handle exceptions of type Error //... return -1; }).onFailed([] { // Handle all other types of errors //... return -1; }); auto result = resultFuture.result(); // result is -1
Si hay múltiples manejadores adjuntos, el primer manejador que coincida con el tipo de excepción lanzada será invocado. Por ejemplo:
QFuture<int> future = someIntFuture; future.then([](int res) { //... throw std::runtime_error("message"); //... }).onFailed([](const std::exception &e) { // This handler will be invoked return -1; }).onFailed([](const std::runtime_error &e) { // This handler won't be invoked, because of the handler above. return -1; });
Si ninguno de los manejadores coincide con el tipo de excepción lanzada, la excepción se propagará al futuro resultante:
QFuture<int> future = someIntFuture; auto resultFuture = future.then([](int res) { //... throw Error("message"); //... return res; }).onFailed([](const std::exception &e) { // Won't be invoked return -1; }).onFailed([](const QException &e) { // Won't be invoked return -1; }); try { auto result = resultFuture.result(); } catch(QException &someException) { // Handle the exception }
Nota: Siempre puedes adjuntar un manejador sin argumento, para manejar todos los tipos de excepción y evitar escribir el bloque try-catch.
Esta función se introdujo en Qt 6.0.
Véase también then() y onCanceled().
[since 6.1] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(QObject *context, Function &&handler)
Adjunta un gestor de fallos a este futuro, para manejar cualquier excepción que el futuro plantee, o que ya haya planteado. Devuelve un QFuture del mismo tipo que este futuro. El manejador será invocado sólo en caso de excepción, en el hilo del objeto context. Esto puede ser útil si el fallo debe ser manejado en un hilo específico. Por ejemplo:
// somewhere in the main thread auto future = QtConcurrent::run([] { // This will run in a separate thread //... throw std::exception(); }).onFailed(this, [] { // Update UI elements });
El manejador de fallos adjuntado en QtConcurrent::run actualiza los elementos de la UI y no puede ser invocado desde un hilo que no sea de la UI. Así que this se proporciona como un contexto a .onFailed(), para asegurarse de que será invocado en el hilo principal.
Si context se destruye antes de que la cadena haya terminado, el futuro se cancela. Véase then() para más detalles.
Nota: Cuando se llama a este método, debe garantizarse que el context permanece vivo durante la configuración de la cadena.
Véase la documentación de la otra sobrecarga para más detalles sobre handler.
Esta es una función sobrecargada.
Esta función se introdujo en Qt 6.1.
Véase también then() y onCanceled().
int QFuture::progressMaximum() const
Devuelve el máximo progressValue().
Véase también progressValue() y progressMinimum().
int QFuture::progressMinimum() const
Devuelve el mínimo progressValue().
Véase también progressValue() y progressMaximum().
QString QFuture::progressText() const
Devuelve la representación textual (opcional) del progreso informado por el cálculo asíncrono.
Tenga en cuenta que no todos los cálculos proporcionan una representación textual del progreso, por lo que esta función puede devolver una cadena vacía.
int QFuture::progressValue() const
Devuelve el valor de progreso actual, que se encuentra entre progressMinimum() y progressMaximum().
Véase también progressMinimum() y progressMaximum().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::result() const
Devuelve el primer resultado en el futuro. Si el resultado no está disponible inmediatamente, esta función se bloqueará y esperará a que el resultado esté disponible. Este es un método conveniente para llamar a resultAt(0). Tenga en cuenta que result() devuelve una copia del resultado almacenado internamente. Si T es un tipo de sólo movimiento, o si no desea copiar el resultado, utilice takeResult() en su lugar.
Nota: Llamar a esta función conduce a un comportamiento indefinido si isValid() devuelve false para este QFuture. Si este QFuture aún no se ha iniciado, llame a waitForFinished() antes de llamar a esta función para evitar un comportamiento indefinido.
Véase también resultAt(), results(), y takeResult().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::resultAt(int index) const
Devuelve el resultado en index en el futuro. Si el resultado no está disponible inmediatamente, esta función se bloqueará y esperará a que el resultado esté disponible.
Nota: Llamar a esta función conduce a un comportamiento indefinido si isValid() devuelve false para este QFuture. Si este QFuture aún no se ha iniciado, llame a waitForFinished() antes de llamar a esta función para evitar un comportamiento indefinido.
Véase también result(), results(), takeResult(), y resultCount().
int QFuture::resultCount() const
Devuelve el número de resultados continuos disponibles en este futuro. El número real de resultados almacenados podría ser diferente de este valor, debido a huecos en el conjunto de resultados. Siempre es seguro iterar por los resultados desde 0 hasta resultCount().
Véase también result(), resultAt(), results() y takeResult().
template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QList<T> QFuture::results() const
Devuelve todos los resultados del futuro. Si los resultados no están disponibles inmediatamente, esta función se bloqueará y esperará a que estén disponibles. Tenga en cuenta que results() devuelve una copia de los resultados almacenados internamente. La obtención de todos los resultados de un tipo de sólo movimiento T no está soportada por el momento. Sin embargo, puedes iterar a través de la lista de resultados de sólo movimiento utilizando iteradores de estilo STL o iteradores de sólo lectura de estilo Java.
Nota: Llamar a esta función conduce a un comportamiento indefinido si isValid() devuelve false para este QFuture. Si este QFuture aún no se ha iniciado, llame a waitForFinished() antes de llamar a esta función para evitar un comportamiento indefinido.
Véase también result(), resultAt(), takeResult(), resultCount(), y isValid().
void QFuture::resume()
Reanuda el cómputo asíncrono representado por future(). Este es un método de conveniencia que simplemente llama a setSuspended(false).
Véase también suspend().
[since 6.0] void QFuture::setSuspended(bool suspend)
Si suspend es verdadero, esta función suspende el cálculo asíncrono representado por future(). Si el cálculo ya está suspendido, esta función no hace nada. QFutureWatcher no dejará inmediatamente de enviar señales de progreso y de resultado listo cuando se suspenda el futuro. En el momento de la suspensión puede haber todavía cálculos en curso que no pueden detenerse. Las señales para dichos cálculos seguirán enviándose.
Si suspend es falso, esta función reanuda el cálculo asíncrono. Si el cálculo no se suspendió previamente, esta función no hace nada.
Tenga en cuenta que no todos los cálculos pueden suspenderse. Por ejemplo, el QFuture devuelto por QtConcurrent::run() no puede suspenderse; pero el QFuture devuelto por QtConcurrent::mappedReduced() sí puede.
Esta función se introdujo en Qt 6.0.
Véase también isSuspended(), suspend(), resume(), y toggleSuspended().
[since 6.0] void QFuture::suspend()
Suspende el cálculo asíncrono representado por este futuro. Este es un método conveniente que simplemente llama a setSuspended(true).
Esta función se introdujo en Qt 6.0.
Véase también resume().
[since 6.0] template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::takeResult()
Llame a esta función sólo si isValid() devuelve true, de lo contrario el comportamiento es indefinido. Esta función toma (mueve) el primer resultado del objeto QFuture, cuando sólo se espera un resultado. Si hay otros resultados, se descartan después de tomar el primero. Si el resultado no está disponible inmediatamente, esta función se bloqueará y esperará a que el resultado esté disponible. QFuture intentará utilizar la semántica move si es posible, y volverá a la construcción copy si el tipo no es movible. Después de tomar el resultado, isValid() se evaluará como false.
Nota: QFuture en general permite compartir los resultados entre diferentes objetos QFuture (y potencialmente entre diferentes hilos). takeResult() fue introducido para hacer que QFuture también funcione con tipos move-only (como std::unique_ptr), por lo que asume que sólo un hilo puede mover los resultados fuera del futuro, y hacerlo sólo una vez. También hay que tener en cuenta que tomar la lista de todos los resultados no está soportado por el momento. Sin embargo, aún puedes iterar a través de la lista de resultados de sólo mover usando iteradores de estilo STL o iteradores de sólo lectura de estilo Java.
Esta función se introdujo en Qt 6.0.
Ver también result(), results(), resultAt(), y isValid().
[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(Function &&function)
Adjunta una continuación a este futuro, permitiendo encadenar múltiples cálculos asíncronos si se desea, utilizando la política Sync. function es un callable que toma un argumento del tipo empaquetado por este futuro si este tiene un resultado (no es un QFuture<void>). En caso contrario no toma argumentos. Este método devuelve un nuevo QFuture que empaqueta un valor del tipo devuelto por function. El futuro devuelto estará en un estado no inicializado hasta que la continuación adjunta sea invocada, o hasta que este futuro falle o sea cancelado.
Nota: Utiliza otras sobrecargas de este método si necesitas lanzar la continuación en un hilo separado.
Puedes encadenar múltiples operaciones de este modo:
QFuture<int> future = ...; future.then([](int res1){ ... }).then([](int res2){ ... })...
O:
QFuture<void> future = ...; future.then([](){ ... }).then([](){ ... })...
La continuación también puede tomar un argumento QFuture (en lugar de su valor), que representa el futuro anterior. Esto puede ser útil si, por ejemplo, QFuture tiene múltiples resultados, y el usuario quiere acceder a ellos dentro de la continuación. O el usuario necesita manejar la excepción del futuro anterior dentro de la continuación, para no interrumpir la cadena de múltiples continuaciones. Por ejemplo:
QFuture<int> future = someIntFuture; future.then([](QFuture<int> f) { try { //... auto result = f.result(); //... } catch (QException &e) { // handle the exception } }).then([](){/*...*/});
Advertencia: Si el futuro anterior contiene múltiples resultados de tipo T, y la continuación toma un argumento de tipo T como parámetro, ¡sólo el primer resultado del QFuture anterior será manejado en la continuación!
Si el futuro anterior lanza una excepción y no se maneja dentro de la continuación, la excepción se propagará al futuro de la continuación, para permitir que la persona que llama la maneje:
QFuture<int> future = someIntFuture; auto continuation = future.then([](int res1){ /*...*/ return res1; }).then([](int res2){ /*...*/ return res2; })/*...*/; //... // future throws an exception try { auto result = continuation.result(); } catch (QException &e) { // handle the exception }
En este caso se interrumpirá toda la cadena de continuaciones.
Nota: Si este futuro se cancela, las continuaciones adjuntas a él también se cancelarán.
Esta es una función sobrecargada.
Esta función se introdujo en Qt 6.0.
Véase también onFailed() y onCanceled().
[since 6.1] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QObject *context, Function &&function)
Adjunta una continuación a este futuro, permitiendo encadenar múltiples cálculos asíncronos si se desea. Cuando el cálculo asíncrono representado por este futuro finaliza, function será invocado en el hilo del objeto context. Esto puede ser útil si la continuación necesita ser invocada en un hilo específico. Por ejemplo:
// somewhere in the main thread auto future = QtConcurrent::run([] { // This will run in a separate thread //... }).then(this, [] { // Update UI elements });
La continuación adjunta en QtConcurrent::run actualiza los elementos UI y no puede ser invocada desde un hilo no-gui. Así que this se proporciona como un contexto a .then(), para asegurarse de que será invocada en el hilo principal.
Las siguientes continuaciones también serán invocadas desde el mismo contexto, a menos que se especifique un contexto o política de lanzamiento diferente:
auto future = QtConcurrent::run([] { //... }).then(this, [] { // Update UI elements }).then([] { // This will also run in the main thread });
Esto se debe a que por defecto .then() se invoca desde el mismo hilo que la anterior.
Pero ten en cuenta que si la continuación se adjunta después de que este futuro ya haya terminado, se invocará inmediatamente, en el hilo que ejecuta then():
QObject *context /*...*/; auto future = cachedResultsReady ? QtFuture::makeReadyVoidFuture() : QtConcurrent::run([] { /* compute result */}); auto continuation = future.then(context, [] { // Runs in the context's thread }).then([] { // May or may not run in the context's thread });
En el ejemplo anterior, si cachedResultsReady es true, y se devuelve un futuro listo, es posible que el primer .then() termine antes de que se adjunte el segundo. En este caso se resolverá en el hilo actual. Por lo tanto, en caso de duda, pase el contexto explícitamente.
Si el context se destruye antes de que la cadena haya terminado, el futuro se cancela. Esto implica que un manejador de cancelación podría ser invocado cuando el context ya no es válido. Para evitarlo, captura context como QPointer:
QObject *context /*...*/; QFuture<Result> future /*...*/; auto continuation = future.then(context, [context](Result result) { // ... }).onCanceled([context = QPointer(context)] { if (!context) return; // context was destroyed already // handle cancellation });
Cuando se destruye el objeto de contexto, la cancelación se produce inmediatamente. Los futuros anteriores de la cadena no se cancelan y siguen ejecutándose hasta que finalizan.
Nota: Cuando se llama a este método, se debe garantizar que el context permanece vivo durante la configuración de la cadena.
Esta es una función sobrecargada.
Esta función se introdujo en Qt 6.1.
Véase también onFailed() y onCanceled().
[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QThreadPool *pool, Function &&function)
Adjunta una continuación a este futuro, permitiendo encadenar múltiples cálculos asíncronos si se desea. Cuando el cálculo asíncrono representado por este futuro finalice, function se programará en pool.
Se trata de una función sobrecargada.
Esta función se introdujo en Qt 6.0.
Véase también onFailed() y onCanceled().
[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QtFuture::Launch policy, Function &&function)
Adjunta una continuación a este futuro, permitiendo encadenar múltiples cálculos asíncronos. Cuando el cálculo asíncrono representado por este futuro finaliza, function será invocado de acuerdo con el lanzamiento dado policy. Se devuelve un nuevo QFuture que representa el resultado de la continuación.
Dependiendo de policy, la continuación se invocará en el mismo hilo que este futuro, en un nuevo hilo, o heredará la política de lanzamiento y el grupo de hilos de este futuro. Si no se especifica ninguna política de lanzamiento (véase la sobrecarga que sólo toma un callable), se utilizará la política Sync.
En el siguiente ejemplo ambas continuaciones serán invocadas en un nuevo hilo (pero en el mismo).
QFuture<int> future = ...; future.then(QtFuture::Launch::Async, [](int res){ ... }).then([](int res2){ ... });
En el siguiente ejemplo ambas continuaciones serán invocadas en nuevos hilos utilizando el mismo pool de hilos.
QFuture<int> future = ...; future.then(QtFuture::Launch::Async, [](int res){ ... }) .then(QtFuture::Launch::Inherit, [](int res2){ ... });
Consulte la documentación de la otra sobrecarga para más detalles sobre function.
Esta es una función sobrecargada.
Esta función se introdujo en Qt 6.0.
Véase también onFailed() y onCanceled().
[since 6.0] void QFuture::toggleSuspended()
Cambia el estado suspendido de la computación asíncrona. En otras palabras, si el cómputo está actualmente suspendido o en suspensión, al llamar a esta función se reanuda; si el cómputo está en ejecución, se suspende. Este es un método de conveniencia para llamar a setSuspended(!(isSuspending() || isSuspended())).
Esta función se introdujo en Qt 6.0.
Véase también setSuspended(), suspend(), y resume().
[since 6.4] template <typename U> QFuture<U> QFuture::unwrap()
Desenvuelve el futuro interno de este QFuture<T>, donde T es un futuro de tipo QFuture<U>, es decir, este futuro tiene tipo de QFuture<QFuture<U>>. Por ejemplo:
unwrappedFuture se cumplirá tan pronto como se cumpla el futuro interno anidado dentro de outerFuture, con el mismo resultado o excepción y en el mismo hilo que informa del futuro interno como finalizado. Si el futuro interno se cancela, unwrappedFuture también se cancelará.
Esto es especialmente útil cuando se encadenan varios cálculos, y uno de ellos devuelve un QFuture como tipo de resultado. Por ejemplo, digamos que queremos descargar múltiples imágenes desde una URL, escalar las imágenes, y reducirlas a una sola imagen usando QtConcurrent::mappedReduced(). Podríamos escribir algo como
auto downloadImages = [] (const QUrl &url) { QList<QImage> images; //... return images; }; auto processImages = [scale, reduceImages](const QList<QImage> &images) { return QtConcurrent::mappedReduced(images, scale, reduceImages); }; auto show = [](const QImage &image) { /*...*/ }; auto future = QtConcurrent::run(downloadImages, url) .then(processImages) .unwrap() .then(show);
Aquí QtConcurrent::mappedReduced() devuelve un QFuture<QImage>, así que .then(processImages) devuelve un QFuture<QFuture<QImage>>. Como show() toma un QImage como argumento, el resultado de .then(processImages) no se le puede pasar directamente. Necesitamos llamar a .unwrap(), que obtendrá el resultado del futuro interno cuando esté listo y lo pasará a la siguiente continuación.
En caso de anidamiento múltiple, .unwrap() desciende hasta el nivel más interno:
Esta función se introdujo en Qt 6.4.
void QFuture::waitForFinished()
Espera a que finalice el cálculo asíncrono (incluidos los cálculos de cancel()ed), es decir, hasta que isFinished() devuelva true.
QFuture<T> &QFuture::operator=(const QFuture<T> &other)
Asigna other a este futuro y devuelve una referencia a este futuro.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.