Rotate a QWidget



  • Hi,
    from an external library i get a live view of a codereader.

    The function looks like:

    HWND monitorHandle = reinterpret_cast<HWND>(ui->widget->winId());
    CreateLiveViewW(monitorHandle, "192.168.0.5");
    

    Unfortunately the image is upside down. So i thought to flip/rotate the QWidget.

    So i subclassed QWidget and override the paintEvent function.

    void MyWidget::paintEvent(QPaintEvent *event) override
    {
        QPainter painter(this);
        painter.rotate(180);
    }
    

    But the image is still upside down. So i think i need to add some stuff to the QPainter, but i have no idea what ...

    Can someone help?

    Thanks!



  • @beecksche said in Rotate a QWidget:

    Unfortunately the image is upside down

    Do you have a QImage?



  • @VRonin
    No.

    I try something like this:

    void MyWidget::paintEvent(QPaintEvent *event)
    {
        QPixmap pixmap = grab();
    
        QPainter painter(this);
        painter.rotate(180);
        painter.drawPixmap(x(), y(), pixmap.width(), pixmap.height(), pixmap);
    }
    


  • Try something like follows. It should work.

    void RotateImage::paintEvent(QPaintEvent *event)
    {
    QPainter paint(this);
    QPixmap map(200,200);
    if (!map.load("myphoto.JPG")) {
    qDebug() << " Load fail "<<endl;
    return;
    }
    paint.translate(200,200);
    paint.rotate(90);
    paint.drawPixmap(0,0,200,200,map);



  • @beecksche said in Rotate a QWidget:

    @VRonin
    No.

    I try something like this:

    void MyWidget::paintEvent(QPaintEvent *event)
    {
        QPixmap pixmap = grab();
    
        QPainter painter(this);
        painter.rotate(180);
        painter.drawPixmap(x(), y(), pixmap.width(), pixmap.height(), pixmap);
    }
    

    This can't possibly work. I'm afraid we need more context to be able to help you, what is MyWidget? how does it get the upside-down image in the first place?


  • Moderators

    If the external library operates on HWND then there's nothing you can do in Qt to rotate what it paints. It doesn't use Qt at all so rotating some painter in Qt doesn't affect it in any way. You'll need to find a way to flip the view in that 3rd party library api if it has such functionality. If not then you could check if you can transfer the rendered pixels to some image (e.g. using BitBlt ) or render to an offscreen bitmap and flip that. Qt can't help you there as you're operating on native handles.



  • @Chris-Kawa
    Thanks for the information. I already thought that it isn't that easy ...

    But now i found the source code. It's not really nice to read. But i think i found what they are doing. Here are the relevant code parts:

    The HWND, which i have to pass at the beginning in

    int WINAPI CreateLiveViewW(HWND hWnd, LPCWSTR lpAddr);
    

    is used to create a device context

    HDC hdc = ::GetDC(m_hWnd);
    m_hDc = ::CreateCompatibleDC(hdc);
    

    The image of the codereader is than be drawn with

    BOOL CMImage::DecodeImage(BYTE *pDstBuf,int nDstSize)
    {
    	CImage cImg;
    
    	BYTE *pImageFile;
    	IStream *pIStream;
    	HGLOBAL hImageFile;
    	HRESULT hr;
    	hImageFile = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, nDstSize);
    	pImageFile = (BYTE *)GlobalLock(hImageFile);
    	memcpy(pImageFile,pDstBuf,nDstSize);
    	::GlobalUnlock(hImageFile);
    	hr = ::CreateStreamOnHGlobal(hImageFile,TRUE,&pIStream);
    
    	if(FAILED(hr)) {
    		::GlobalFree(hImageFile);
    		return FALSE;
    	}
    
    	try{
    		hr = cImg.Load(pIStream);
    		if(FAILED(hr)) {
    			pIStream->Release();
    			return FALSE;
    		}
    	}
    	catch(...) {
    		pIStream->Release();
    		return FALSE;
    	}
    
    	pIStream->Release();
    
    	SetSize(cImg.GetWidth(),cImg.GetHeight(),FALSE);
    
    	cImg.BitBlt(m_hDc,0,0);
    	return TRUE;
    }
    

  • Moderators

    Is that your code that calls this CMImage::DecodeImage method? Do you have access to that pDstBuf buffer? If so then you could probably skip that library render and create a QImage out of that buffer (if the format is right maybe even without copying the data). You could then draw that image in a paint event with transformation to the painter applied.



  • @Chris-Kawa
    Yes, i have access to pDstBuf. So do mean instead of calling the BitBlt function i should try to create a QImage of the buffer and send it to the paintEvent in the Widget? The format should be JPG.

    Will try it tomorrow! Thanks

    Edit:

    Sorry for my delayed reply. I found a option in the config file of the codereader to rotate the picture! So i do not need to change the source code. Thanks for all your help!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.