2011-11-21 9 views
13

Ho una semplice applicazione che esegue un processo che può durare diversi minuti prima del completamento. Quindi sto cercando di fornire un indicatore all'utente che sta elaborando la richiesta, come cambiare il cursore in una clessidra.Come posso cambiare la forma del cursore con PyQt?

Ma non riesco a farlo funzionare correttamente. Tutti i miei tentativi hanno portato a un errore o non hanno avuto alcun effetto. E mi sembra di chiamare i cursorshapes in modo errato PyQt4.Qt.WaitCursor restituisce un errore che il modulo non lo contiene.

Qual è il modo corretto per indicare all'utente che il processo è in esecuzione?

risposta

34

penso QApplication.setOverrideCursor è quello che stai cercando: soluzione

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

Grazie, funziona perfettamente. – TimothyAWiseman

+0

Nota: Funziona con PyQt4. Tuttavia PySide 1.2.2 sotto Linux (Ubuntu 16.10) dice "Errore X: BadCursor (parametro Cursor non valido) 6" "Opcode principale: 2 (X_ChangeWindowAttributes)" "ID risorsa: 0xa". Feeding setOverrideCursor (Qt.WaitCursor) di PySide invece di setOverrideCursor (QCursor (Qt.WaitCursor)) funziona, nonostante la documentazione che dice che è necessario QCursor(). In alcune circostanze, c'è un errore simile per il ripristino. Questo sembra essere un bug PySide noto. – Ubuntourist

+0

@Uuntourist. Grazie - Posso confermare l'errore in PySide. La classe 'QCursor' ha un costruttore di copie che prende un valore enum' Qt.CursorShape', quindi non è veramente necessario usare 'QCursor' stesso. Suppongo che la creazione del 'QCursor' sul lato Qt sia ciò che corregge il problema di PySide. – ekhumoro

9

di ekhumoro è corretta. Questa soluzione è una modifica per motivi di stile. Ho usato quello che ha fatto l'ekhumor ma ho usato un decoratore pitone.

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 

Posso semplicemente mettere il decoratore su qualsiasi metodo su cui vorrei che lo spinner fosse attivo.

class MyWigdet(QMainWidget): 

    # ... 

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

Il decoratore è una grande idea, grazie. Consiglierei di chiamare 'function (* args, ** kwargs)', restituendo il valore di ritorno di 'function' e avvolgendo la sua chiamata in un blocco 'try ... finally' per ancora più bontà. Non riesco a inserirlo in questo commento, quindi proveremo a modificare la tua soluzione. –

+1

Cambiare il blocco try su 'return function (* args, ** kwargs)' potrebbe essere utile, o almeno nel mio caso. –

0

Meglio così:

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

Mentre le risposte di Cameron e David di sono grandi per l'impostazione del cursore di attesa su un intero funzione, trovo che un manager contesto funziona meglio per l'impostazione del cursore di attesa per i frammenti di codice:

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() 

quindi inserire il codice lungo processo in un blocco con:

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

Questo è il più semplice, elegante e versatile – Schollii

Problemi correlati