gerdb
19th February 2015, 00:19
Hi,
i tried to get the desktop as screenshot and then display exactly the part of it which my widget/window overlaps in the widget's background.
i work on a pc with 2 monitors and get different result ( both are broken ) for each
Left Monitor (primary):
- Image gets distorted on Window resize
- Image contains the widget itself, and i dont know how to hide it during screenshoting the desktop
i tried hide, get screenshot, show with setUpdateEnabled false and true again, but some events still are fired -> infinite loop, bad crash
Right Monitor:
- cant copy part of Screenshot, it is always the full screenshot as widget-background
So my most important questions will be:
1. How do i hide and show widget without getting floods of event, signals
2. How do i get the QScreen object from the widget position
3. What are your opinions/suggestions
TransparentPanel.h
#include <QWidget>
#include <QPixmap>
// ================================================== ==========================
/// @class TransparentPanel
// ================================================== ==========================
class TransparentPanel : public QWidget
{
Q_OBJECT
public:
private:
QPixmap mBG;
public:
///@brief Constructor
explicit TransparentPanel( QWidget* parent = 0 );
///@brief Destructor
~TransparentPanel();
void updateBG();
protected:
virtual void paintEvent( QPaintEvent* event ) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void moveEvent( QMoveEvent* event) override;
// virtual void enterEvent( QEvent* event ) override;
// virtual void leaveEvent( QEvent* event ) override;
// virtual void mousePressEvent ( QMouseEvent* event );
// virtual void mouseReleaseEvent ( QMouseEvent* event );
};
TransparentPanel.cpp
#include "TransparentPanel.h"
#ifndef VERBOSE
#define VERBOSE 1
#endif
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QDebug>
// ================================================== ==========================
TransparentPanel::TransparentPanel( QWidget* parent )
: QWidget(parent)
// ================================================== ==========================
{
setMinimumSize(10,10);
setSizePolicy(QSizePolicy::Expanding,QSizePolicy:: Expanding);
setAutoFillBackground( false );
//setAttribute( Qt::WA_OpaquePaintEvent );
setAttribute( Qt::WA_NoSystemBackground );
//setAttribute( Qt::WA_TranslucentBackground );
setUpdatesEnabled( true );
//MMDebug("TransparentPanel::TransparentPanel()\n")
//MMDebug("QApplication::desktop()->winId() = %x\n", (void*)QApplication::desktop()->winId() )
//MMDebug("GetDesktopWindow() = %x\n", (void*)GetDesktopWindow() )
updateBG();
}
// ================================================== ==========================
TransparentPanel::~TransparentPanel()
// ================================================== ==========================
{
//MMDebug("TransparentPanel::~TransparentPanel()\n")
}
// ================================================== ==========================
void TransparentPanel::paintEvent( QPaintEvent* event )
// ================================================== ==========================
{
if (!isVisible())
return;
//MMDebug("TransparentPanel::paintEvent()\n")
QPainter dc(this);
dc.setRenderHint( QPainter::NonCosmeticDefaultPen );
//dc.fillRect( rect(), Qt::white);
if (!mBG.isNull())
{
dc.drawPixmap( rect(), mBG);
}
QWidget::paintEvent(event);
}
// ================================================== ==========================
void TransparentPanel :: resizeEvent(QResizeEvent* event)
// ================================================== ==========================
{
//MMDebug("TransparentPanel::resizeEvent()\n")
updateBG();
//QWidget::resizeEvent(event);
}
// ================================================== ==========================
void TransparentPanel::moveEvent( QMoveEvent* event)
// ================================================== ==========================
{
//MMDebug("TransparentPanel::moveEvent()\n")
updateBG();
//QWidget::moveEvent(event);
}
//// ================================================== ==========================
//void TransparentPanel::enterEvent( QEvent* event )
//// ================================================== ==========================
//{
// QWidget::enterEvent(event);
//}
//// ================================================== ==========================
//void TransparentPanel::leaveEvent( QEvent* event )
//// ================================================== ==========================
//{
// QWidget::leaveEvent(event);
//}
//// ================================================== ==========================
//void TransparentPanel :: mousePressEvent ( QMouseEvent* event )
//// ================================================== ==========================
//{
// QWidget::mousePressEvent( event );
//}
//// ================================================== ==========================
//void TransparentPanel :: mouseReleaseEvent ( QMouseEvent* event )
//// ================================================== ==========================
//{
// QWidget::mouseReleaseEvent( event );
//}
// ================================================== ==========================
void TransparentPanel::updateBG()
// ================================================== ==========================
{
// if (!isVisible())
// return;
//// setVisible(false);
// mBG = QPixmap(); // clear image for low memory situations on weak devices.
// QPoint screenTopLeft = mapToGlobal( geometry().topLeft() );
// int x = screenTopLeft.x();
// int y = screenTopLeft.y();
// int w = width();
// int h = height();
// //mBG = QPixmap::grabWindow(QApplication::desktop()->winId(), x,y, w,h );
// //QScreen* screen = QApplication::screens()->primaryScreen();
// QScreen* screen = QApplication::primaryScreen();
// if (screen)
// //mBG = screen->grabWindow(QApplication::desktop()->window()->winId(), x,y, w,h );
// mBG = screen->grabWindow((WId)GetDesktopWindow(), x,y, w,h );
//// setVisible(true);
// update();
QRect g = geometry();
QPoint p1 = mapToGlobal( g.topLeft() );
QPoint p2 = mapToGlobal( g.bottomRight() );
// setVisible(false);
QPoint screenTopLeft = mapToGlobal( pos() );
int ax = screenTopLeft.x();
int ay = screenTopLeft.y();
int aw = width();
int ah = height();
QRect r( p1, p2 );
// QImage img = pix.toImage();
// for ( int j = 0; j < img.height(); ++j )
// {
// for ( int i = 0; i < img.width(); ++i )
// {
// QColor c = img.pixel(i,j);
// c.setAlpha(255);
// img.setPixel( i,j, c.rgba() );
// }
// }
// //QImage img = pix.toImage();
// dc.drawImage( rect(), img );
// setUpdatesEnabled(false);
// hide();
//QPixmap pix = QDesktopWidget().grab( QRect(x,y,w,h) );
//QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId(), x,y, w,h );
//QPixmap screenShot = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow() );
//mBG = screenShot.copy( ax,ay,aw,ah );
//mBG = screenShot.copy( r );
// mBG = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow(), r.left(), r.top(), r.width(), r.height() );
QPixmap scr = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow() );
mBG = scr.copy( r );
#ifdef VERBOSE
std::stringstream s;
s << "pos ( x=" << pos().x() << ",y=" << pos().y() << ")\n";
s << "a ( x=" << ax << ",y=" << ay << ",w=" << aw << ",h=" << ah << ")\n";
s << "g ( x=" << g.left() << ",y=" << g.top() << ",w=" << g.width() << ",h=" << g.height() << ")\n";
s << "r ( x=" << r.left() << ",y=" << r.top() << ",w=" << r.width() << ",h=" << r.height() << ")\n";
s << "scr ( w=" << scr.width() << ",h=" << scr.height() << ")\n";
s << "mBG ( w=" << mBG.width() << ",h=" << mBG.height() << ")\n";
qDebug() << QString::fromStdString(s.str());
//MMPrint("%s", s.str().c_str())
#endif
// show();
// setUpdatesEnabled(true);
update();
}
i tried to get the desktop as screenshot and then display exactly the part of it which my widget/window overlaps in the widget's background.
i work on a pc with 2 monitors and get different result ( both are broken ) for each
Left Monitor (primary):
- Image gets distorted on Window resize
- Image contains the widget itself, and i dont know how to hide it during screenshoting the desktop
i tried hide, get screenshot, show with setUpdateEnabled false and true again, but some events still are fired -> infinite loop, bad crash
Right Monitor:
- cant copy part of Screenshot, it is always the full screenshot as widget-background
So my most important questions will be:
1. How do i hide and show widget without getting floods of event, signals
2. How do i get the QScreen object from the widget position
3. What are your opinions/suggestions
TransparentPanel.h
#include <QWidget>
#include <QPixmap>
// ================================================== ==========================
/// @class TransparentPanel
// ================================================== ==========================
class TransparentPanel : public QWidget
{
Q_OBJECT
public:
private:
QPixmap mBG;
public:
///@brief Constructor
explicit TransparentPanel( QWidget* parent = 0 );
///@brief Destructor
~TransparentPanel();
void updateBG();
protected:
virtual void paintEvent( QPaintEvent* event ) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void moveEvent( QMoveEvent* event) override;
// virtual void enterEvent( QEvent* event ) override;
// virtual void leaveEvent( QEvent* event ) override;
// virtual void mousePressEvent ( QMouseEvent* event );
// virtual void mouseReleaseEvent ( QMouseEvent* event );
};
TransparentPanel.cpp
#include "TransparentPanel.h"
#ifndef VERBOSE
#define VERBOSE 1
#endif
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QDebug>
// ================================================== ==========================
TransparentPanel::TransparentPanel( QWidget* parent )
: QWidget(parent)
// ================================================== ==========================
{
setMinimumSize(10,10);
setSizePolicy(QSizePolicy::Expanding,QSizePolicy:: Expanding);
setAutoFillBackground( false );
//setAttribute( Qt::WA_OpaquePaintEvent );
setAttribute( Qt::WA_NoSystemBackground );
//setAttribute( Qt::WA_TranslucentBackground );
setUpdatesEnabled( true );
//MMDebug("TransparentPanel::TransparentPanel()\n")
//MMDebug("QApplication::desktop()->winId() = %x\n", (void*)QApplication::desktop()->winId() )
//MMDebug("GetDesktopWindow() = %x\n", (void*)GetDesktopWindow() )
updateBG();
}
// ================================================== ==========================
TransparentPanel::~TransparentPanel()
// ================================================== ==========================
{
//MMDebug("TransparentPanel::~TransparentPanel()\n")
}
// ================================================== ==========================
void TransparentPanel::paintEvent( QPaintEvent* event )
// ================================================== ==========================
{
if (!isVisible())
return;
//MMDebug("TransparentPanel::paintEvent()\n")
QPainter dc(this);
dc.setRenderHint( QPainter::NonCosmeticDefaultPen );
//dc.fillRect( rect(), Qt::white);
if (!mBG.isNull())
{
dc.drawPixmap( rect(), mBG);
}
QWidget::paintEvent(event);
}
// ================================================== ==========================
void TransparentPanel :: resizeEvent(QResizeEvent* event)
// ================================================== ==========================
{
//MMDebug("TransparentPanel::resizeEvent()\n")
updateBG();
//QWidget::resizeEvent(event);
}
// ================================================== ==========================
void TransparentPanel::moveEvent( QMoveEvent* event)
// ================================================== ==========================
{
//MMDebug("TransparentPanel::moveEvent()\n")
updateBG();
//QWidget::moveEvent(event);
}
//// ================================================== ==========================
//void TransparentPanel::enterEvent( QEvent* event )
//// ================================================== ==========================
//{
// QWidget::enterEvent(event);
//}
//// ================================================== ==========================
//void TransparentPanel::leaveEvent( QEvent* event )
//// ================================================== ==========================
//{
// QWidget::leaveEvent(event);
//}
//// ================================================== ==========================
//void TransparentPanel :: mousePressEvent ( QMouseEvent* event )
//// ================================================== ==========================
//{
// QWidget::mousePressEvent( event );
//}
//// ================================================== ==========================
//void TransparentPanel :: mouseReleaseEvent ( QMouseEvent* event )
//// ================================================== ==========================
//{
// QWidget::mouseReleaseEvent( event );
//}
// ================================================== ==========================
void TransparentPanel::updateBG()
// ================================================== ==========================
{
// if (!isVisible())
// return;
//// setVisible(false);
// mBG = QPixmap(); // clear image for low memory situations on weak devices.
// QPoint screenTopLeft = mapToGlobal( geometry().topLeft() );
// int x = screenTopLeft.x();
// int y = screenTopLeft.y();
// int w = width();
// int h = height();
// //mBG = QPixmap::grabWindow(QApplication::desktop()->winId(), x,y, w,h );
// //QScreen* screen = QApplication::screens()->primaryScreen();
// QScreen* screen = QApplication::primaryScreen();
// if (screen)
// //mBG = screen->grabWindow(QApplication::desktop()->window()->winId(), x,y, w,h );
// mBG = screen->grabWindow((WId)GetDesktopWindow(), x,y, w,h );
//// setVisible(true);
// update();
QRect g = geometry();
QPoint p1 = mapToGlobal( g.topLeft() );
QPoint p2 = mapToGlobal( g.bottomRight() );
// setVisible(false);
QPoint screenTopLeft = mapToGlobal( pos() );
int ax = screenTopLeft.x();
int ay = screenTopLeft.y();
int aw = width();
int ah = height();
QRect r( p1, p2 );
// QImage img = pix.toImage();
// for ( int j = 0; j < img.height(); ++j )
// {
// for ( int i = 0; i < img.width(); ++i )
// {
// QColor c = img.pixel(i,j);
// c.setAlpha(255);
// img.setPixel( i,j, c.rgba() );
// }
// }
// //QImage img = pix.toImage();
// dc.drawImage( rect(), img );
// setUpdatesEnabled(false);
// hide();
//QPixmap pix = QDesktopWidget().grab( QRect(x,y,w,h) );
//QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId(), x,y, w,h );
//QPixmap screenShot = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow() );
//mBG = screenShot.copy( ax,ay,aw,ah );
//mBG = screenShot.copy( r );
// mBG = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow(), r.left(), r.top(), r.width(), r.height() );
QPixmap scr = QApplication::primaryScreen()->grabWindow( (WId)GetDesktopWindow() );
mBG = scr.copy( r );
#ifdef VERBOSE
std::stringstream s;
s << "pos ( x=" << pos().x() << ",y=" << pos().y() << ")\n";
s << "a ( x=" << ax << ",y=" << ay << ",w=" << aw << ",h=" << ah << ")\n";
s << "g ( x=" << g.left() << ",y=" << g.top() << ",w=" << g.width() << ",h=" << g.height() << ")\n";
s << "r ( x=" << r.left() << ",y=" << r.top() << ",w=" << r.width() << ",h=" << r.height() << ")\n";
s << "scr ( w=" << scr.width() << ",h=" << scr.height() << ")\n";
s << "mBG ( w=" << mBG.width() << ",h=" << mBG.height() << ")\n";
qDebug() << QString::fromStdString(s.str());
//MMPrint("%s", s.str().c_str())
#endif
// show();
// setUpdatesEnabled(true);
update();
}