deng186 2024-09-10 16:41 采纳率: 0%
浏览 7

QT linux 刷新截屏

QT 刷新及截屏问题:

这是新创建的基于QMainWindow的程序, 默认情况下是白色背景, 我有如下需求,
点击一个按钮,槽函数为GrabWindow,
期望结果是:
执行一个循环,依次将窗口背景设为红、绿、蓝,每次设为背景色后截屏并存成文件,即得到红、绿、蓝三张图片。
实际结果:
得到白(程序初始化得白色)、红、绿三张图片, 貌似每次截图都是上次的背景色,当前设置的颜色未立即生效。
processEvents()调用后不是应该刷新完成了吗?

void QtGuiApplication1::GrabWindow()
{
    static QStringList styles;
    if(styles.isEmpty())
    {
        styles.append("background-color:#FF0000");
        styles.append("background-color:#00FF00");
        styles.append("background-color:#0000FF");
    }
    for(int i = 0; i < styles.length(); i++)
    {
        setStyleSheet(styles[i]);
        repaint();
        QCoreApplication::processEvents();
        QScreen *screen = QGuiApplication::primaryScreen();
        QPixmap screenshot = screen->grabWindow(0);
        char path[100] = {0};
        sprintf(path, "/home/screen %d.png",i+1);
        bool ret = screenshot.save(path,"PNG");
        qDebug() << "Save " << ret;
    }
}

  • 写回答

2条回答 默认 最新

  • 一轮明月照丘壑 2024-09-10 17:01
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从你的代码来看,你正在尝试改变窗口的背景色并立即截图。然而,setStyleSheet()repaint()并不保证立即更新窗口的内容。即使你调用了processEvents(),也可能由于操作系统的渲染机制和其他因素导致截图并不是最新的窗口内容。这可能是因为操作系统并没有完成渲染过程,因此截图捕获的是未更新的窗口状态。以下是一些可能的解决方案:

    1. 使用定时器:使用QTimer来延迟截图操作,确保窗口有足够的时间更新。这样可以在颜色改变后等待一段时间再进行截图。
    2. 重写绘图事件:如果你需要更精细的控制窗口的渲染过程,可以重写paintEvent()函数。在这个函数中,你可以根据需要在窗口上绘制不同的背景色,并确保在绘制完成后进行截图。

    以下是使用定时器的示例代码:

    void QtGuiApplication1::GrabWindow()
    {
        static QStringList styles;
        if(styles.isEmpty())
        {
            styles.append("background-color:#FF0000");
            styles.append("background-color:#00FF00");
            styles.append("background-color:#0000FF");
        }
        for(int i = 0; i < styles.length(); i++)
        {
            setStyleSheet(styles[i]);
            repaint();
            QTimer::singleShot(100, this, [this, i]() { // 延迟一段时间进行截图
                QScreen *screen = QGuiApplication::primaryScreen();
                QPixmap screenshot = screen->grabWindow(0);
                char path[100] = {0};
                sprintf(path, "/home/screen %d.png",i+1);
                bool ret = screenshot.save(path,"PNG");
                qDebug() << "Save " << ret;
            });
        }
    }
    

    这种方法使用了定时器来延迟截图操作,确保在颜色改变后有一定的时间间隔再进行截图,从而捕获到最新的窗口内容。注意这里使用了C++的lambda表达式来捕获当前循环的索引i

    评论

报告相同问题?

问题事件

  • 创建了问题 9月10日

悬赏问题

  • ¥15 Coze智能助手搭建过程中的问题请教
  • ¥15 12864只亮屏 不显示汉字
  • ¥20 三极管1000倍放大电路
  • ¥15 vscode报错如何解决
  • ¥15 前端vue CryptoJS Aes CBC加密后端java解密
  • ¥15 python随机森林对两个excel表格读取,shap报错
  • ¥15 基于STM32心率血氧监测(OLED显示)相关代码运行成功后烧录成功OLED显示屏不显示的原因是什么
  • ¥100 X轴为分离变量(因子变量),如何控制X轴每个分类变量的长度。
  • ¥30 求给定范围的全体素数p的(p-2)/p的连乘积值
  • ¥15 VFP如何使用阿里TTS实现文字转语音?