单击时在 QWidget 上绘制矩形叠加层 [英] Draw Rectangular overlay on QWidget at click

查看:65
本文介绍了单击时在 QWidget 上绘制矩形叠加层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我将 EventFilter 用于小部件,它们位于 QHBoxLayout 中.

in my project i use a EventFilter for widgets, that are in a QHBoxLayout.

如果我点击了一个小部件,我想在点击的小部件上绘制一个蓝色的透明叠加层.有没有办法实现这个?

If i clicked on an a widget, i want to draw a transparent overlay with blue color over the clicked widget. Is there a way to implement this?

问候

推荐答案

这个答案是在我与叠加层相关的一系列答案中:第一第二第三个.

This answer is in a series of my overlay-related answers: first, second, third.

一种方法是:

  1. 有一个对鼠标事件也透明的半透明覆盖小部件.

  1. Have a semi-transparent overlay widget that is also transparent to mouse events.

在事件过滤器中,通过调整叠加层的几何形状以匹配目标小部件的几何形状来跟踪对象的点击和调整大小.

In the event filter, track the clicks and the resizing of the objects by adjusting the overlay's geometry to match that of the target widget.

下面的自包含示例在 Qt 4 和 Qt 5 下都可以运行,并且可以满足您的需求.

The self-contained example below works under both Qt 4 and Qt 5 and does what you want.

// https://github.com/KubaO/stackoverflown/tree/master/questions/overlay-19199863
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif

class Overlay : public QWidget {
public:
    explicit Overlay(QWidget *parent = nullptr) : QWidget(parent) {
        setAttribute(Qt::WA_NoSystemBackground);
        setAttribute(Qt::WA_TransparentForMouseEvents);
    }
protected:
    void paintEvent(QPaintEvent *) override {
        QPainter(this).fillRect(rect(), {80, 80, 255, 128});
    }
};

class OverlayFactoryFilter : public QObject {
    QPointer<Overlay> m_overlay;
public:
    explicit OverlayFactoryFilter(QObject *parent = nullptr) : QObject(parent) {}
protected:
    bool eventFilter(QObject *obj, QEvent *ev) override {
        if (!obj->isWidgetType()) return false;
        auto w = static_cast<QWidget*>(obj);
        if (ev->type() == QEvent::MouseButtonPress) {
            if (!m_overlay) m_overlay = new Overlay;
            m_overlay->setParent(w);
            m_overlay->resize(w->size());
            m_overlay->show();
        }
        else if (ev->type() == QEvent::Resize) {
            if (m_overlay && m_overlay->parentWidget() == w)
                m_overlay->resize(w->size());
        }
        return false;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    OverlayFactoryFilter factory;
    QWidget window;
    QHBoxLayout layout(&window);
    for (auto text : { "Foo", "Bar", "Baz "}) {
        auto label = new QLabel{text};
        layout.addWidget(label);
        label->installEventFilter(&factory);
    }
    window.setMinimumSize(300, 250);
    window.show();
    return a.exec();
}

这篇关于单击时在 QWidget 上绘制矩形叠加层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆