13

私のプロジェクトでは、EventFilterにあるウィジェットに を使用していますQHBoxLayout

ウィジェットをクリックした場合、クリックしたウィジェットの上に青色の透明なオーバーレイを描画したいと考えています。これを実装する方法はありますか?

挨拶

4

2 に答える 2

21

この回答は、一連のオーバーレイ関連の回答です: firstsecondthird

それを行う1つの方法は次のとおりです。

  1. マウス イベントに対しても透明な半透明のオーバーレイ ウィジェットを用意します。

  2. イベント フィルタで、オーバーレイのジオメトリをターゲット ウィジェットのジオメトリと一致するように調整して、オブジェクトのクリックとサイズ変更を追跡します。

以下の自己完結型の例は、Qt 4 と Qt 5 の両方で機能し、必要なことを行います。

スクリーンショット

// 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();
}
于 2013-10-05T19:40:25.310 に答える
2

オーバーレイ ウィジェット コンストラクターで:

    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();
于 2017-02-28T17:24:16.133 に答える