窗口/屏幕上发生任何更改时的 Qt 事件 + 屏幕截图

Posted

技术标签:

【中文标题】窗口/屏幕上发生任何更改时的 Qt 事件 + 屏幕截图【英文标题】:Qt event when anything changed on the window/screen + Screenshot 【发布时间】:2015-11-24 01:03:59 【问题描述】:

我正在考虑扩展 QT4 应用程序并提供一些调试功能,以便更轻松地分析客户问题。应用程序已经有一个“调试”模式,当它被启用时,会产生很多日志条目,很难阅读。 我想要实现的是在 GUI 上发生更改时截取应用程序的屏幕截图。我知道它可能会拍很多照片,但一般很长一段时间都没有启用Debug模式。问题是我找不到这样的事件/信号。所以我有两个问题:

    有这样的活动我可以订阅吗?我的意思是,一个事件是 每当屏幕上发生任何变化时触发。 我可以使用 Qt 截取应用程序的屏幕截图吗?

提前致谢!

【问题讨论】:

【参考方案1】:

我会使用一个事件过滤器和一个 QTimer,像这样:

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();

【讨论】:

【参考方案2】:

一般来说,当某些小部件发生变化时,Qt 需要重新绘制它,所以您感兴趣的事件是QEvent::Paint。这里的问题是,对于相互重叠的小部件,会有大量此类事件。您可以覆盖 QApplication::notify() 以在所有绘制事件被传递给接收者之前捕获它们。

至于制作 Qt 应用程序的屏幕截图 - SO 上有几个类似的问题,例如 screenshot of a qt application from inside the application 或 Taking screenshot of a specific window - C++ / Qt

Here 也是一个讨论将小部件转储到paintEvent() 中的图像的线程。

【讨论】:

【参考方案3】:

至于你的第二个问题,here 是我的一些旧代码,可以截取一个窗口。您可以像这样使用此代码:

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

然后您可以将 HBITMAP 转换为 Qt Pixmap 对象并按照您的喜好使用它:QPixmap pixmap = QPixmap::fromWinHBITMAP(image);

编辑:这是特定于 Windows 的代码,不确定其他系统上的等效代码。

【讨论】:

请注意,此代码是特定于 Windows 的,因此这样做会使程序不可移植。 好电话,我忘了提。

以上是关于窗口/屏幕上发生任何更改时的 Qt 事件 + 屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX:如何在屏幕上的任何位置检测鼠标/键事件?

即使窗口重叠,如何在 Qt(Python、Linux)中截取特定窗口的屏幕截图?

Qt的窗口如何显示在spi屏幕上

Qt多文档实现屏幕空间(类似监控多画面)效果

屏幕关闭时的 iBeacon 事件

窗口/舞台失去焦点时的事件