2011-11-21 12 views
13

Tengo una aplicación simple que ejecuta un proceso que puede durar varios minutos antes de completarse. Por lo tanto, intento proporcionar un indicador al usuario de que está procesando la solicitud, como cambiar el cursor a un reloj de arena.¿Cómo puedo cambiar la forma del cursor con PyQt?

Pero no puedo hacer que funcione bien. Todos mis intentos dieron como resultado un error o no tuvieron ningún efecto. Y parece que llamar incorrectamente a las formas del cursor. PyQt4.Qt.WaitCursor devuelve un error de que el módulo no lo contiene.

¿Cuál es la forma correcta de indicar al usuario que el proceso se está ejecutando?

Respuesta

34

creo QApplication.setOverrideCursor es lo que está buscando: solución

from PyQt4.QtCore import Qt 
from PyQt4.QtGui import QApplication 
... 
QApplication.setOverrideCursor(Qt.WaitCursor) 
# do lengthy process 
QApplication.restoreOverrideCursor() 
+0

Gracias, eso funciona a la perfección. – TimothyAWiseman

+0

Nota: Esto funciona en PyQt4. Sin embargo, PySide 1.2.2 en Linux (Ubuntu 16.10) dice "X Error: BadCursor (parámetro del Cursor no válido) 6" "Opcode mayor: 2 (X_ChangeWindowAttributes)" "Identificación del recurso: 0xa". Alimentar el SetOverrideCursor (Qt.WaitCursor) de PySide en lugar de setOverrideCursor (QCursor (Qt.WaitCursor)) funciona, a pesar de que la documentación dice que se necesita el QCursor(). En algunas circunstancias, hay un error similar para la restauración. Esto parece ser un error conocido de PySide. – Ubuntourist

+0

@Ubuntourist. Gracias - Puedo confirmar el error en PySide. La clase 'QCursor' tiene un constructor de copia que toma un valor de enum' Qt.CursorShape', por lo que no es realmente necesario usar 'QCursor'. Supongo que crear el 'QCursor' en el lado de Qt es lo que corrige el problema de PySide. – ekhumoro

9

de ekhumoro es correcta. Esta solución es una modificación por el estilo. Usé lo que hizo el ekhumor, pero usé un decorador de pitones.

from PyQt4.QtCore import Qt 
from PyQt4.QtGui import QApplication, QCursor, QMainWidget 

def waiting_effects(function): 
    def new_function(self): 
     QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 
     try: 
      function(self) 
     except Exception as e: 
      raise e 
      print("Error {}".format(e.args[0])) 
     finally: 
      QApplication.restoreOverrideCursor() 
    return new_function 

puedo sólo hay que poner el decorador en cualquier método me gustaría que el spinner a estar activo en.

class MyWigdet(QMainWidget): 

    # ... 

    @waiting_effects 
    def doLengthyProcess(self): 
     # do lengthy process 
     pass 
+1

El decorador es una gran idea, gracias. Recomiendo llamar 'function (* args, ** kwargs)', devolver 'return' function', y envolver su llamada en un bloque' try ... finally' para aún más bondad. Parece que no puedo poner eso en este comentario, así que a continuación intentaré editar su solución. –

+1

Cambiar el bloque try a 'return function (* args, ** kwargs)' podría ser útil también, o al menos en mi caso. –

0

Mejor así:

def waiting_effects(function): 
    def new_function(*args, **kwargs): 
     QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 
     try: 
      return function(*args, **kwargs) 
     except Exception as e: 
      raise e 
      print("Error {}".format(e.args[0])) 
     finally: 
      QApplication.restoreOverrideCursor() 
    return new_function 
7

Mientras respuestas de David Cameron y de son excelentes para fijar el cursor de espera más de una función entera, considero que un gestor de contexto que funciona mejor para establecer el cursor de espera para los fragmentos de código:

from contextlib import contextmanager 
from PyQt4 import QtCore 
from PyQt4.QtGui import QApplication, QCursor 

@contextmanager 
def wait_cursor(): 
    try: 
     QApplication.setOverrideCursor(QCursor(QtCore.Qt.WaitCursor)) 
     yield 
    finally: 
     QApplication.restoreOverrideCursor() 

a continuación, poner el código largo proceso en un bloque con:

with wait_cursor(): 
    # do lengthy process 
    pass 
+0

Esto es más simple, más elegante y versátil – Schollii

Cuestiones relacionadas