Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: ElderOrb от Август 29, 2006, 14:54 для вывода изображения с камеры использую QWidget с paintEngine = 0, упакованный в QScrollArea (пробовал выводить просто в QWidget - наблюдал неприятные мерцания и т.п. при скроллинге и ресайзе не зависимо от состояния оконных флагов!!!) Т.к. paintEngine = 0, отрисовать что-то поверх изображения с камеры с помощью QPainter-а нереально. А надо. Приходится отрисовывать через winAPI, для функций которого нужен HDC. Если получать hdc через QWidget::getDC() / releaseDC() то при скроллинге отрисовка производится не полностью а иногда не производится вовсе!.. если же через апишные - GetDC() / ReleaseDC() - почти ок. Баг? Вот код, иллюстрирующий вышесказанное:
bool mvsstand::eventFilter(QObject *o, QEvent *e) { if(o == w) { if(e->type() == QEvent::Paint) { QWidget *that_widget = w; w = 0; QApplication::sendEvent(o, e); w = that_widget; // такой способ работает HDC dc = GetDC(w->winId()); // а такой - нет ! //HDC dc = w->getDC(); HPEN pen = CreatePen(PS_SOLID, 1, RGB(0,0xFF,0xFF)); SelectObject(dc, pen); SetTextColor(dc, RGB(0xFF,0,0)); LineTo(dc, 100, 100); qDebug("paint event, %d", QTime::currentTime()); /* QPainter p(w); p.fillRect(0, 0, 100, 100, Qt::green); */ DeleteObject(pen); //w->releaseDC(dc); ReleaseDC(w->winId(), dc); return true; } } return QMainWindow::eventFilter(o, e); } Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: Admin от Август 29, 2006, 21:25 я свой код публиковал мерцаний нет
еще раз маленький исходник #include "ibrs.h" CFastImage::CFastImage(QWidget* parent) : QWidget(parent) { m_data=NULL; setAttribute( Qt::WA_PaintOnScreen, true); } CFastImage::~CFastImage() { if(m_data!=NULL) delete[] m_data; } void CFastImage::paintEvent(QPaintEvent* p) { // just for illustration purposes. You get the same effect if you leave the paint event completely empty, too. QWidget::paintEvent(p); BITMAPINFO BMP; BMP.bmiHeader.biWidth=width; BMP.bmiHeader.biHeight=height; BMP.bmiHeader.biBitCount=24; BMP.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); BMP.bmiHeader.biPlanes = 1; BMP.bmiHeader.biCompression = BI_RGB; BMP.bmiHeader.biSizeImage = ( ( BMP.bmiHeader.biWidth * ( BMP.bmiHeader.biBitCount >> 3 ) + 3 ) & - 4 ) * BMP.bmiHeader.biHeight; HDC hdc = GetDC(winId()); SetStretchBltMode( hdc, COLORONCOLOR ); StretchDIBits ( hdc , 0 , 0 , width , height , 0 , 0 , width , height , m_data , &BMP , DIB_RGB_COLORS , SRCCOPY ); ReleaseDC(winId(), hdc); } QPaintEngine* CFastImage::paintEngine() const { return 0; } Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: ElderOrb от Август 29, 2006, 22:02 Спасибо за пример, но у меня похоже несколько иная ситуация. Библиотека распознавания сама пишет захваченные кадры в окно (там создаётся объект которому нужен hwnd окна и он занимается всем).
Мне же надо поверх выводить свою графику. Если я правильно понял, я смогу частично использовать вышеизложенный подход для вывода своей информации, для чего надо делать как-то так: писать всё что я хочу отрисовать в QImage, в paintEvent-е заполнять структуру BITMAPINFO и через StretchDIBits отрисовывать на экран используя в качестве данных QImage::bits() ? Если это заработает (а это я проверю завтра) будет отлично!.. Хотя в идеале хотелось бы сохранить Qt-шную paintEngine-у для большего удобства рисования. В ходе экспериментов с оконными флагами возник ещё вопрос, почему так странно работает нижиприведённый код. Странности следующие: 1. независимо от того, что написано в paintEvent-е ни на что не влияют оконные флаги, (т.е при рисовании через QPainter всё ок, через gdi - непрорисовывает вообще или прорисовывает частично и со страшным мерцанием). 2. HDC dc = w->getDC(); возвращает 0 !!! Код:
p.s. хотел удобства ради запостить весь проект да обнаружил что некак ж). Может быть стоит ввести такую фичу в форум? Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: Admin от Август 30, 2006, 00:40 только мысля:
при ресайзе скорее всего приходят 2 типа сообщений QEvent::Paint и QEvent::Resize причем как извесно отрисовка это самая низкоприоритетная задача возможно тут сабака и зарыта далее нашел в исходниках QPaintDevice /*! \internal */ HDC QPaintDevice::getDC() const { return 0; } /*! \internal */ void QPaintDevice::releaseDC(HDC) const { } на что то похоже PS: проект можно упаковать и прилипить на форум в виде zip или rar файла Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: ElderOrb от Август 30, 2006, 10:53 Что-то у меня не получается черз битмэп. ж( А ещё я не могу найти где приатачить файл к форуму. Поэтому снова кидаю код сюда. Буду очень благодарен за информацию где же я затупил в этот раз ж) w - потомок QWidget-а с paintEngine = 0 (хотя если она и не ноль - ничего не меняется) на экране - пусто ж(
bool PaintingTest::eventFilter(QObject* o, QEvent* e) { if(o == w) { if(e->type() == QEvent::Paint) { /* QWidget* ww = w; w = 0; QApplication::sendEvent(o, e); w = ww; */ int width = w->width(); int height = w->height(); QImage image(width, height, QImage::Format_RGB32); QPainter p; p.begin(&image); p.drawLine(0,0, 100, 100); p.fillRect(200, 200, 50, 50, Qt::green); p.end(); BITMAPINFO BMP; BMP.bmiHeader.biWidth=width; BMP.bmiHeader.biHeight=height; BMP.bmiHeader.biBitCount=24; BMP.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); BMP.bmiHeader.biPlanes = 1; BMP.bmiHeader.biCompression = BI_RGB; BMP.bmiHeader.biSizeImage = ( ( BMP.bmiHeader.biWidth * ( BMP.bmiHeader.biBitCount >> 3 ) + 3 ) & - 4 ) * BMP.bmiHeader.biHeight; HDC hdc = GetDC(winId()); SetStretchBltMode( hdc, COLORONCOLOR ); StretchDIBits ( hdc , 0 , 0 , width , height , 0 , 0 , width , height , image.bits() , &BMP , DIB_RGB_COLORS , SRCCOPY ); ReleaseDC(winId(), hdc); return false; } } return QMainWindow::eventFilter(o, e); } Название: Qt 4.1.4 - баг в getDC() / ReleaseDC() ? Отправлено: Admin от Август 30, 2006, 12:21 ну первое что видно
в QImage 32 бита на точку а в bitmap 24 Image image(width, height, QImage::Format_RGB32); BMP.bmiHeader.biBitCount=24; 2 вещь: не забываем что в BMP снизу вверх отчет идет, мак мать его |