Save parts of screen to image file
-
Hello,
I'm having an odd problem when trying to save parts of the screen in my window (i.e. a screenshot) to an image file. It works on the first call, but the subsequent calls simply write the first screenshot over again.
I'm coding a QGuiApplication, with QWindow. Somewhere in the QWindow-inherited class (outside any Qt/OpenGl rendering), I call:
m_context->screen()->grabWindow(winId(),x,y,w,h).save(QString("test.bmp"));
m_context is a QOpenGLContext, with the OpenGLSurface surface type.
Any ideas to why this only works on the first call (and then seems to "freeze" somehow)?
-
Hi,
Can you provide a more complete example that shows the problem ?
-
Here's a minimalist code snippet, MainWindow inherits QWindow:
@MainWindow::MainWindow(QWindow *parent) :
QWindow(parent),
m_context(0),
m_device(0),
{
setWidth(WINDOWRESX);
setHeight(WINDOWRESY);
setSurfaceType(QWindow::OpenGLSurface);
}bool MainWindow::event(QEvent *event)
{
switch (event->type()) {
case QEvent::UpdateRequest:
render();
return true;
default:
return QWindow::event(event);
}
}void MainWindow::exposeEvent(QExposeEvent *event)
{
Q_UNUSED(event);
if (isExposed())
startRender();
}void MainWindow::render()
{
if (!m_device)
m_device = new QOpenGLPaintDevice;m_device->setSize(size()); QPainter painter(m_device); glClearColor(.75f,.75f,.75f,1.0f); // background colour glViewport(0,0,width(),height()); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); painter.beginNativePainting(); // start OpenGL painting
openGL drawing
painter.endNativePainting(); render(&painter);
}
void MainWindow::render(QPainter *painter)
{
draw with painter
}void MainWindow::startRender()
{
if (!isExposed())
return;bool needsInitialize = false; if (!m_context) { m_context = new QOpenGLContext(this); m_context->setFormat(requestedFormat()); m_context->create(); needsInitialize = true; initialize(); } m_context->makeCurrent(this); if (needsInitialize) { initializeOpenGLFunctions(); } render(); m_context->swapBuffers(this);
}
void MainWindow::keyPressEvent(QKeyEvent *ev)
{
if(ev->key()==Qt::Key_S) { // save file
int x = 50, y = 50, w = 500, h = 500;
m_context->screen()->grabWindow(winId(),x,y,w,h).save(QString(“test.bmp”));
}
}@ -
Shouldn't you make the context current before doing a grabWindow ?
-
Nope, that didn't solve the problem; that is, the image that is being saved is still the first saved image, even if I delete the "old" image before I press S again. The edited keyPressEvent:
@void MainWindow::keyPressEvent(QKeyEvent *ev)
{
if(ev->key()==Qt::Key_S) { // save file
int x = 50, y = 50, w = 500, h = 500;
m_context->makeCurrent(this);
m_context->screen()->grabWindow(winId(),x,y,w,h).save(QString(“test.bmp”));
}
}@ -
Did you try grabWidget ?