1

I'm thinking of extending a QT4 application with some debug possibilities, to make it easier analyzing customer issues. The application already has a "Debug" mode, when this is enabled, a lot of log entries generated, which is hard to read. What I would like to achive is taking a screenshot of the application, whenever something is changed on the GUI. I know that it may take a lot of pictures, but generally Debug mode is not enabled for a long time. The problem is I cannot find such an event/signal. So I have two question:

  1. Is there such an event I could subscribe? I mean, an event that is fired whenever anything changes on the screen.
  2. Can I take a screenshot of the application using Qt?

Thanks in advance!

3 Answers3

3

I'd do it using an event filter and a QTimer, something like this:

class MyEventFilter : public QObject
{
public:
   MyEventFilter() : _screenshotPending(false) {/* empty */}

   virtual bool eventFilter(QObject * o, QEvent * e)
   {
      if (e->type() == QEvent::Paint)
      {
         if (_screenshotPending == false)
         {
            // we'll wait 500mS before taking the screenshot
            // that way we aren't trying to take 1000 screenshots per second :)
            _screenshotPending = true;
            QTimer::singleShot(500, this, SLOT(TakeAScreenshot()));
         }
      }
      return QObject::eventFilter(o, e);
   }

public slots:
   void TakeAScreenshot()
   {
      _screenshotPending = false;

      // add the standard Qt code for taking a screenshot here
      // see $QTDIR/examples/widgets/desktop/screenshot for that
   }

private:
   bool _screenshotPending;  // true iff we've called QTimer::singleShot() recently
};

int main(int argc, char ** argv)
{
   MyEventFilter filter;

   QApplication app(argc, argv);
   app.installEventFilter(&filter);
   [...]

   return app.exec();
}
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
1

Generally, when some widget changes Qt needs to repaint it, so the event you would be interested in is QEvent::Paint. The problem here is that there will be tons of these events for widgets that overlap each other. You can override QApplication::notify() to catch all paint events before they are even delivered to receivers.

As for making screenshots of Qt application - there are several similar questions here on SO, for example screenshot of a qt application from inside the application or Taking screenshot of a specific window - C++ / Qt

Here is also a thread discussing dumping widgets to images in paintEvent().

Community
  • 1
  • 1
Paul
  • 13,042
  • 3
  • 41
  • 59
0

As for your second question, here is some of my old code that can take a screenshot of a window. You can use this code like so:

HDC WinDC = GetDC(HWND_OF_YOUR_WINDOW);
HBITMAP image = ScreenshotUtility::fromHDC(WinDC);

Then you can convert the HBITMAP to a Qt Pixmap object and work with it how you like: QPixmap pixmap = QPixmap::fromWinHBITMAP(image);.

EDIT: this is Windows-specific code, not sure what the equivalent on other systems may be.

Nick Cano
  • 437
  • 2
  • 7