2013-06-11 23 views
9

Mam QGLWidget, który renderuje scenę OpenGL wewnątrz aplikacji Qt. Chciałbym dodać inne przezroczyste widżety Qt, które są nakładane na QGLWidget. Jest to trudniejsze niż w przypadku standardowych widżetów, ponieważ kontekst rysowania OpenGL jest nieznany klasom malarskim Qt. Tak więc, jeśli po prostu robię oczywistą rzecz i umieszczam przezroczysty pasek narzędzi na przykład na QGLWidget, przezroczysta część paska narzędziowego renderuje czarny (nie ma dostępu do bufora ramki OpenGL podczas malowania).W jaki sposób można zapobiec malowaniu obiektu QWidget, ale nadal odpowiadać na zdarzenia?

Wygląda na to, że zalecanym sposobem postępowania z takimi rzeczami jest overpaint the 2D content after drawing the OpenGL scene. Połączony przykład wydaje się bardzo prosty, o ile tylko rysujesz proste kształty. Zamiast tego, chciałbym odłożyć obraz jakiegoś obiektu dla dziecka QWidget, który ma zostać wykonany wewnątrz zdarzenia malowania dla QGLWidget.

Więc mój problem sprowadza się do tego:

  1. Prevent nakładka QWidget s od malarstwa w normalnym, 2D kontekście.
  2. W programie obsługi zdarzeń dla farby QGLWidget pomaluj nakładki po pomalowaniu sceny 3D, która tworzy tło.

Druga pozycja na tej liście wydaje się być prosta: można używać QWidget::render() wewnątrz farby przypadku gdy QGLWidget „s zwrócić żądane widgety na górze rzutni. Działa to dobrze.

Pierwszy element jest trudniejszy: Potrzebuję sposobu, aby zapobiec malowaniu widżetów podczas normalnego przebiegu zdarzeń i malować je tylko w programie do malowania QGLWidget. Jednym z oczywistych sposobów na to jest ukrywanie nakładek za pomocą QWidget::hide(). To pozwala mi malować widżety na szczycie sceny OpenGL, tak jakbym chciał. Ponieważ widżety są ukryte, nie reagują na zdarzenia myszy ani klawiatury. Na przykład używam przycisku QToolBar z kilkoma przyciskami, a pasek narzędzi jest odpowiednio pomalowany, ale nie działa (żaden z przycisków nie reaguje na kliknięcia). Tak więc, jeśli podążę tą ścieżką, wydaje mi się, że potrzebowałabym sposobu na to, aby widżet nadal reagował na zdarzenia, mimo że jest ukryty.

Innym podejściem, które próbowałem, było przechwycenie zdarzenia malowania QToolBar przy użyciu filtru zdarzeń, w celu uniemożliwienia malowania samego paska narzędzi. Jednak pasek narzędzi jest nadal renderowany; Zakładam, że dzieje się tak dlatego, że różne przyciski na pasku narzędzi to widżety potomne, które wciąż są malowane, nawet jeśli przechwycę zdarzenie malowania rodzica.

Jakieś pomysły dotyczące sposobu, w jaki mógłbym osiągnąć mój cel?

Odpowiedz

12

Nie rozumiem twojego problemu całkowicie, ale postaram się odpowiedzieć na pytanie zawarte w tytule. Powinieneś użyć filtrów zdarzeń. Zainstaluj filtr zdarzeń, używając widget->installEventFilter(object), gdzie widget jest widgetem, który chcesz zablokować malowaniem, a object jest obiektem dowolnej z twoich klas pochodnych QObject. Reimplement eventFilter tej klasy:

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

Po powrocie prawda z eventFilter, zdarzenie jest filtrowana i farby nie występuje.

Możesz także spróbować użyć widget->setUpdatesEnabled(false), aby tymczasowo wyłączyć malowanie. Nie zapomnij włączyć go ponownie, gdy skończysz.