Drawing an overlay on top of an application's

2019-03-18 16:14发布

问题:

I want to be able to paint on top of my application's window so that I can annotate all the widgets with some extra diagnostic information, similar to the CSS developer tools in Firefox (eg add widget classes, styles, highlight borders etc).

I can walk the widget tree and extract the relevant information, but the question is how can I overlay all the application windows with this information?

One way would be to override my QMainWindow's paint event, but this has to be done for all top level windows. Is there an alternative method where you can paint on the QDesktopWidget for instance? Or any hooks into each QWidget's paint method? Anything that involves subclassing QWidget itself won't work with the standard widgets.

This follows on from my previous question:

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

cheers Mandrill

EDIT: Thanks to Dmitry I've now got a really simple method that is easily extensible:

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:

You can create own style class based on QMotifStyle or other ... and paint on any widget/control related to him information.

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;

    }
}


回答2:

This wiki explains about drawing something on a QWidget.

http://developer.nokia.com/community/wiki/Archived:How_to_overlay_QWidget_on_top_of_another

You might want to do something like this.



标签: qt paint