单击时在QWidget上绘制矩形叠加层

在我的项目中,我使用了一个EventFilter来处理部件,它们在QHBoxLayout

如果我点击一个小部件,我想绘制一个透明的覆盖与蓝色的点击小部件。 有没有办法来实现这个?

问候

这个答案是在一系列与覆盖有关的答案中: 第一 , 第二 , 第三 。

一种做法是:

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

  2. 在事件filter中,通过调整覆盖图的几何graphics来匹配目标窗口小部件的几何graphics,从而跟踪对象的点击和resize。

下面的自包含的例子在Qt 4和Qt 5下工作,并且做你想要的。

截图

 // https://github.com/KubaO/stackoverflown/tree/master/questions/overlay-19199863.pro #include <QtGui> #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) #include <QtWidgets> #endif class Overlay : public QWidget { public: 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 Filter : public QObject { QPointer<Overlay> m_overlay; QPointer<QWidget> m_overlayOn; public: Filter(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(w->parentWidget()); m_overlay->setGeometry(w->geometry()); m_overlayOn = w; m_overlay->show(); } else if (ev->type() == QEvent::Resize) { if (m_overlay && m_overlayOn == w) m_overlay->setGeometry(w->geometry()); } return false; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); Filter filter; QWidget window; QHBoxLayout layout(&window); for (auto text : { "Foo", "Bar", "Baz "}) { auto label = new QLabel{text}; layout.addWidget(label); label->installEventFilter(&filter); } window.setMinimumSize(300, 250); window.show(); return a.exec(); } 

在覆盖小部件构造函数中:

  setWindowFlags(Qt::Widget | Qt::FramelessWindowHint | Qt::ToolTip | Qt::WindowStaysOnTopHint); setAttribute(Qt::WA_NoSystemBackground, true); setAttribute(Qt::WA_TranslucentBackground, true); 

在拥有该小部件的窗口中:

 overlay_ = new RtspOverlay(this); overlay_->show();