2013-06-11 2 views
9

У меня есть QGLWidget, который создает сцену OpenGL внутри приложения Qt. Я хотел бы добавить некоторые другие полупрозрачные Qt-виджеты, которые накладываются поверх QGLWidget. Это сложнее, чем со стандартными виджетами, поскольку контекст рисования OpenGL неизвестен классам живописцев Qt. Итак, если я просто делаю очевидную вещь и, например, размещаю прозрачную панель инструментов поверх QGLWidget, прозрачная часть панели инструментов делает черный (она не имеет доступа к буферу кадра OpenGL при рисовании).Как я могу предотвратить появление QWidget, но реагировать на события?

Кажется, что рекомендуемый способ обращения с такими вещами - overpaint the 2D content after drawing the OpenGL scene. Связанный пример кажется очень простым, если вы просто рисуете простые фигуры. Вместо этого мне хотелось бы отложить картину некоторых дочерних объектов QWidget, которые должны быть сделаны внутри события рисования для QGLWidget.

Итак, моя проблема сводится к следующему:

  1. Предотвращение наложения QWidget s из картины в нормальном, 2D контексте.
  2. В обработчике событий краски для QGLWidget нарисуйте накладки после рисования 3D-сцены, которая составляет фон.

Второй пункт в этом списке, кажется простым: я могу использовать QWidget::render() в случае расписывать QGLWidget «s, чтобы сделать нужные виджеты в верхней части окна просмотра. Это прекрасно работает.

Первый элемент более сложный: мне нужен способ предотвратить рисование виджета во время обычного хода событий и рисовать их только в обработчике краски QGLWidget. Один из очевидных способов сделать это - скрыть наложения с помощью QWidget::hide(). Это позволяет мне рисовать виджеты поверх сцены OpenGL, как хотелось бы. Однако, поскольку виджеты скрыты, они не реагируют на события мыши или клавиатуры. В качестве примера я использую QToolBar с несколькими кнопками на нем, и панель инструментов нарисована правильно, но не работает (ни одна из кнопок не реагирует на щелчки). Итак, если идти по этому пути, кажется, мне нужен способ заставить виджет по-прежнему реагировать на события, даже если он скрыт.

Другой подход, который я пробовал, заключается в том, чтобы перехватить событие рисования QToolBar с использованием фильтра событий с целью предотвращения самокраски панели инструментов. Однако панель инструментов по-прежнему отображается; Я предполагаю, что это связано с тем, что различные кнопки на панели инструментов являются дочерними виджетами, которые все еще окрашены, даже если я перехватываю событие рисования родителя.

Любые идеи на пути, которым я мог бы выполнить свою цель?

ответ

12

Я полностью не понимаю вашу проблему, но я постараюсь ответить на вопрос, указанный в названии. Вы должны использовать фильтры событий. Установите фильтр событий, используя widget->installEventFilter(object), где widget - это виджет, который вы хотите заблокировать покраску, а object - объект любого из ваших классов, основанных на QObject. Перепишите eventFilter этого класса:

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

Когда вы возвращаетесь истину от вашего eventFilter, событие фильтруется и краска не происходит.

Вы также можете использовать widget->setUpdatesEnabled(false), чтобы временно отключить рисование. Не забудьте снова включить его, когда закончите.

Смежные вопросы