I am trying to use Windows GDI inside a QGraphicsView paintEvent, but noticed some problems with painting, for example, the painting disappears or blinks when I resize the window or minimize and maximize it. When I use Qt instead of GDI, it works fine. Here is the code:
[UPDATED CODE]
#include "CustomView.h" #include <QPainter> #include <QPaintEngine> #include <windows.h> #include <objidl.h> #include <gdiplus.h> using namespace Gdiplus; #pragma comment (lib,"Gdiplus.lib") CustomView::CustomView(QWidget *parent) : QGraphicsView(parent) { setAutoFillBackground(true); setViewportUpdateMode(QGraphicsView::FullViewportUpdate); setAttribute(Qt::WA_NativeWindow, true); } CustomView::~CustomView() { } void CustomView::paintEvent(QPaintEvent * event) { QPainter painter(viewport()); painter.beginNativePainting(); // Drawing by Windows GDI HWND hwnd = (HWND)viewport()->winId(); HDC hdc = GetDC(hwnd); QString text("Test GDI Paint"); RECT rect; GetClientRect(hwnd, &rect); HBRUSH hbrRed = CreateSolidBrush(RGB(0, 255, 0)); FillRect(hdc, &rect, hbrRed); Ellipse(hdc, 50, 50, rect.right - 100, rect.bottom - 100); SetTextAlign(hdc, TA_CENTER | TA_BASELINE); TextOutW(hdc, width() / 2, height() / 2, (LPCWSTR)text.utf16(), text.size()); ReleaseDC(hwnd, hdc); painter.endNativePainting(); QGraphicsView::paintEvent(event); // Drawing the same by Qt // QPainter painter(viewport()); // painter.save() ; // QBrush GreenBrush(Qt::green); // QBrush WhiteBrush(Qt::white); // QRect ViewportRect = viewport()->rect(); // painter.fillRect(ViewportRect, GreenBrush); // painter.drawEllipse(50, 50, ViewportRect.right() - 100, ViewportRect.bottom() - 100); // QPainterPath EllipsePath; // EllipsePath.addEllipse(50, 50, ViewportRect.right() - 100, ViewportRect.bottom() - 100); // painter.fillPath(EllipsePath, WhiteBrush); // painter.drawText(ViewportRect.width() / 2, ViewportRect.height() / 2, "Test Qt Paint"); // painter.restore(); }
and here is the whole project (Visual Studio 2010 + Qt 5.4.1) [UPDATED ARCHIVE] https://dl.dropboxusercontent.com/u/105132532/Stackoverflow/Qt5TestApplication.7z
Any ideas?
Solution (edited code after Cuba Aubert's answer)
#include "CustomView.h" #include <QPainter> #include <QPaintEngine> #include <windows.h> #include <objidl.h> #include <gdiplus.h> using namespace Gdiplus; #pragma comment (lib,"Gdiplus.lib") CustomView::CustomView(QWidget *parent) : QGraphicsView(parent) { // This brings the original paint engine alive. QGraphicsView::paintEngine(); setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); setRenderHint(QPainter::Antialiasing); } CustomView::~CustomView() { } QPaintEngine* CustomView::paintEngine() const { return NULL; } bool CustomView::event(QEvent * event) { if (event->type() == QEvent::Paint) { bool result = QGraphicsView::event(event); drawGDI(); return result; } else if (event->type() == QEvent::UpdateRequest) { bool result = QGraphicsView::event(event); drawGDI(); return result; } return QGraphicsView::event(event); } void CustomView::drawGDI() { // Drawing by Windows GDI HWND hwnd = (HWND)viewport()->winId(); HDC hdc = GetDC(hwnd); QString text("Test GDI Paint"); RECT rect; GetClientRect(hwnd, &rect); HBRUSH hbrRed = CreateSolidBrush(RGB(0, 255, 0)); FillRect(hdc, &rect, hbrRed); Ellipse(hdc, 50, 50, rect.right - 100, rect.bottom - 100); SetTextAlign(hdc, TA_CENTER | TA_BASELINE); TextOutW(hdc, width() / 2, height() / 2, (LPCWSTR)text.utf16(), text.size()); ReleaseDC(hwnd, hdc); }