You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Qt中实现QWidget窗口内容实时同步复制到第三个窗口显示

Qt 窗口实时同步实现方案

方案1:重绘信号触发+离屏渲染(推荐,性能开销低,支持源窗口隐藏场景)

该方案可以实现无延迟同步,且源窗口隐藏后仍然可以正常获取内容:

  • 第一步:修改你的绘图QWidget类,新增重绘完成信号,每次绘图结束后触发
class DrawWidget : public QWidget
{
    Q_OBJECT
signals:
    // 重绘完成信号,将自身指针传出
    void sigRenderDone(DrawWidget* self);
protected:
    void paintEvent(QPaintEvent* event) override
    {
        // 原有绘图逻辑保持不变
        QWidget::paintEvent(event);
        // 绘图完成后触发同步信号
        emit sigRenderDone(this);
    }
};
  • 第二步:实现第三个预览窗口,绑定源控件的重绘信号,收到信号后直接将源控件内容渲染到预览窗口
class PreviewWindow : public QWidget
{
    Q_OBJECT
public:
    explicit PreviewWindow(DrawWidget* source, QWidget* parent = nullptr)
        : QWidget(parent), m_sourceWidget(source)
    {
        // 初始尺寸可和源控件保持一致,也可自定义
        resize(source->size());
        // 绑定信号,源控件每次重绘就同步刷新预览
        connect(source, &DrawWidget::sigRenderDone, this, qOverload<>(&QWidget::update));
    }
protected:
    void paintEvent(QPaintEvent* event) override
    {
        Q_UNUSED(event)
        QPainter painter(this);
        // 将源控件的完整内容渲染到当前预览窗口
        // 如果需要缩放适配预览窗口尺寸,可增加目标矩形、源矩形参数
        m_sourceWidget->render(&painter);
    }
private:
    DrawWidget* m_sourceWidget = nullptr;
};
  • 第三步:初始化时关联即可
// 原有初始化逻辑
DrawWidget* drawWidget = new DrawWidget;
QMainWindow* operateWindow = new QMainWindow; // 你的第二个交互操作窗口
// 初始化预览窗口
PreviewWindow* previewWindow = new PreviewWindow(drawWidget);
previewWindow->show();

优势:源控件隐藏状态下render方法仍然可以正常获取完整绘图内容,所有交互修改会在源控件重绘时立刻同步到预览窗口,延迟基本可忽略,性能开销远低于定时截图方案。

方案2:定时刷新同步(适合不想修改原有DrawWidget代码的场景)

如果你不愿意修改原有绘图控件的代码,可以用定时器定时拉取源控件内容,设置16ms间隔(对应60帧)即可满足实时需求:

class PreviewWindow : public QWidget
{
    Q_OBJECT
public:
    explicit PreviewWindow(DrawWidget* source, QWidget* parent = nullptr)
        : QWidget(parent), m_sourceWidget(source)
    {
        resize(source->size());
        // 启动60帧刷新定时器
        QTimer* refreshTimer = new QTimer(this);
        connect(refreshTimer, &QTimer::timeout, this, qOverload<>(&QWidget::update));
        refreshTimer->start(16);
    }
protected:
    void paintEvent(QPaintEvent* event) override
    {
        Q_UNUSED(event)
        QPainter painter(this);
        m_sourceWidget->render(&painter);
    }
private:
    DrawWidget* m_sourceWidget = nullptr;
};

注意:该方案最多有16ms的同步延迟,性能消耗比方案1略高,适合对同步精度要求不高的场景。

适配说明

如果需要预览窗口和源绘图控件尺寸不同,只要在render方法中传入对应矩形参数即可实现自动缩放:

// 示例:将源内容缩放铺满整个预览窗口
m_sourceWidget->render(&painter, rect(), m_sourceWidget->rect());

如果你的绘图控件使用了OpenGL渲染,替换paintEvent逻辑为调用grabFramebuffer获取帧缓冲内容再绘制即可。

内容的提问来源于stack exchange,提问作者Bidon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:24:01