我试图在QGraphicsView的paintEvent中使用Windows GDI,但发现存在一些绘图问题,例如当我调整窗口大小或最小化和最大化时,绘图会消失或闪烁。当我使用Qt而不是GDI时,它可以完美地工作。以下是代码:
[更新后代码]
#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();
}
这是整个项目(Visual Studio 2010 + Qt 5.4.1)[已更新存档] https://dl.dropboxusercontent.com/u/105132532/Stackoverflow/Qt5TestApplication.7z
有什么想法吗?
解决方案(在Kuba Ober的回答后编辑代码)
#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);
}