2013-06-11 17 views
9

Ho un QGLWidget che esegue il rendering di una scena OpenGL all'interno di un'applicazione Qt. Vorrei aggiungere altri widget Qt traslucidi sovrapposti a QGLWidget. Questo è più difficile rispetto ai widget standard poiché il contesto di disegno OpenGL è sconosciuto alle classi di pittori di Qt. Quindi, se faccio semplicemente la cosa ovvia e posiziono una barra degli strumenti trasparente su QGLWidget, la parte trasparente della barra degli strumenti viene invece resa nera (non ha accesso al frame buffer OpenGL quando si dipinge).Come posso evitare che QWidget dipinga, ma continui a rispondere agli eventi?

Sembra che il modo consigliato per gestire questo tipo di cose sia overpaint the 2D content after drawing the OpenGL scene. L'esempio collegato sembra molto semplice, a patto di disegnare forme semplici. Invece, quello che mi piacerebbe fare è posticipare la verniciatura di alcuni oggetti figlio QWidget all'interno dell'evento paint per QGLWidget.

Quindi, il mio problema si riduce a questo:

  1. Impedire la sovrapposizione QWidget s dalla pittura nel contesto normale, 2D.
  2. Nel gestore di eventi paint per QGLWidget, dipingere le sovrapposizioni dopo aver dipinto la scena 3D che costituisce lo sfondo.

La seconda voce in questa lista sembra essere semplice: posso usare QWidget::render() all'interno dell'evento vernice s' il QGLWidget per disegnare i widget desiderati sulla parte superiore della finestra. Questo funziona bene.

Il primo elemento è più complicato: ho bisogno di un modo per evitare che i widget dipingino durante il normale corso degli eventi e li dipingi solo nel gestore di vernice di QGLWidget. Un modo ovvio per farlo è nascondere le sovrapposizioni usando QWidget::hide(). Questo mi permette di dipingere i widget in cima alla scena OpenGL come vorrei. Tuttavia, poiché i widget sono nascosti, non rispondono agli eventi del mouse o della tastiera. Ad esempio, sto utilizzando uno QToolBar con alcuni pulsanti e la barra degli strumenti è dipinta correttamente, ma non è funzionale (nessuno dei pulsanti risponde ai clic). Quindi, se percorrendo questa strada, sembra che avrei bisogno di un modo per forzare il widget a rispondere ancora agli eventi anche se è nascosto.

Un altro approccio che ho provato è quello di intercettare l'evento paint di QToolBar utilizzando un filtro eventi, con l'obiettivo di impedire alla barra degli strumenti di dipingersi. Tuttavia, la barra degli strumenti è ancora visualizzata; Presumo che ciò sia dovuto al fatto che i vari pulsanti sulla barra degli strumenti sono widget figlio che sono ancora dipinti, anche se intercetto l'evento paint del genitore.

Qualche idea su un modo per raggiungere il mio obiettivo?

risposta

12

Non capisco completamente il problema, ma proverò a rispondere alla domanda indicata nel titolo. Dovresti usare i filtri eventi. Installa un filtro eventi utilizzando widget->installEventFilter(object), dove widget è un widget che desideri bloccare la pittura e object è un oggetto di una delle tue classi derivate da QObject. Reimplementare eventFilter di questa classe:

bool MyClass::eventFilter(QObject* object, QEvent* event) { 
    if (event->type() == QEvent::Paint) { return true; } 
    return false; 
} 

Quando ritorni vero dal vostro eventFilter, l'evento viene filtrata e la vernice non si verifica.

È inoltre possibile provare a utilizzare widget->setUpdatesEnabled(false) per disattivare temporaneamente la pittura. Non dimenticare di riattivarlo quando hai finito.