在应用程序窗口的顶部绘制叠加层

Posted

技术标签:

【中文标题】在应用程序窗口的顶部绘制叠加层【英文标题】:Drawing an overlay on top of an application's window 【发布时间】:2011-05-06 10:11:54 【问题描述】:

我希望能够在我的应用程序窗口顶部进行绘制,以便我可以使用一些额外的诊断信息来注释所有小部件,类似于 Firefox 中的 CSS 开发人员工具(例如添加小部件类、样式、突出显示边框等) .

我可以遍历小部件树并提取相关信息,但问题是如何使用这些信息覆盖所有应用程序窗口?

一种方法是覆盖我的QMainWindow 的绘制事件,但必须对所有***窗口执行此操作。例如,是否有其他方法可以让您在QDesktopWidget 上绘画?或者每个QWidget的绘画方法有什么钩子?任何涉及子类化 QWidget 本身的东西都不适用于标准小部件。

这是我之前的问题:

Are there any useful tools for diagnosing Qt layout and spacing problems?

干杯 山魈

编辑: 感谢 Dmitry,我现在有了一个非常简单且易于扩展的方法:

class DiagnosticStyle : public QWindowsVistaStyle

Q_OBJECT

public: 
    typedef QWindowsVistaStyle BaseStyle;
    void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const;
;


void DiagnosticStyle::drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const

    BaseStyle::drawControl(element, option, painter, widget);
    if (widget && painter) 
        // draw a border around the widget
        painter->setPen(QColor("red"));
        painter->drawRect(widget->rect());

        // show the classname of the widget
        QBrush translucentBrush(QColor(255,246,240, 100));
        painter->fillRect(widget->rect(), translucentBrush);
        painter->setPen(QColor("darkblue"));
        painter->drawText(widget->rect(), Qt::AlignLeft | Qt::AlignVCenter, widget->metaObject()->className()); 
    


qApp->setStyle(new DiagnosticStyle());

【问题讨论】:

【参考方案1】:

您可以基于 QMotifStyle 或其他...创建自己的样式类,并在与他信息相关的任何小部件/控件上进行绘制。

void MyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,QPainter *painter, const QWidget *widget) const

     QStyle::State flags = option->state;
     QRect      rect     = option->rect;
     QPalette   pal      = option->palette;
     QBrush brush;

    switch (element)
    
        case PE_FrameTabWidget:
        
             painter->save();

                 // for example: draw anything on TabWidget
                painter->drawPixmap(rect,centerPm,centerPm.rect());
             painter->restore();
        
        break;
        default:
         QMotifStyle::drawPrimitive(element, option, painter, widget);
         break;

    

【讨论】:

这是个好主意 -- 改写 QStyle::drawControl() 是否更有用,因为这样您可以访问小部件? 原来这正是我所需要的——看我编辑过的帖子【参考方案2】:

在 Qt5 的某个地方,样式(GTK、Windows 等)是内部制作的。现在你需要使用 QCommonStyle。

如果有人想知道如何使用 Qt5+ 做到这一点。这是上面@the_mandrill 代码的独立版本。

class DiagnosticStyle : public QCommonStyle

Q_OBJECT

public: 
    typedef QStyle BaseStyle;
    void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
    
        QCommonStyle::drawControl(element, option, painter, widget);
        if (widget && painter) 
            // draw a border around the widget
            painter->setPen(QColor("red"));
            painter->drawRect(widget->rect());

            // show the classname of the widget
            QBrush translucentBrush(QColor(255,246,240, 100));
            painter->fillRect(widget->rect(), translucentBrush);
            painter->setPen(QColor("darkblue"));
            painter->drawText(widget->rect(), Qt::AlignLeft | Qt::AlignVCenter, widget->metaObject()->className()); 
        
    ;
;

然后,在你的主窗口构造函数调用

qApp->setStyle(new DiagnosticStyle());

【讨论】:

以上是关于在应用程序窗口的顶部绘制叠加层的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 android TV 中使用 3rd 方应用程序在任何屏幕上绘制叠加层?

具有完美定位的叠加层和顶部文本的内联 SVG 元素

是否正在拖动外部窗口?

如何在 Android 上的 Camera 使用的 SurfaceView 上绘制叠加层?

可以使用 MapKit 在地图上添加叠加层吗?

固定元素在 WKWebkit 上移动