软件显示3个小部件:
自定义窗口小部件的一部分(定义为QRect
)需要Event-opaque
,而周围区域必须为Event-transparent
。
我尝试过:
setAttribute(Qt::WA_TransparentForMouseEvents);
但是,自定义的所有子窗口小部件也变得透明。
我也尝试使用setMask
,但随后自定义小部件无法在周围区域进行绘制。
如何实现这种部分事件透明度?
示例(它没有解释完整的问题,只需添加一个测试解决方案的基础):
main.cpp
#include "transparentwidget.hpp"
#include "normalwidget.hpp"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Main Window
NormalWidget window;
window.resize(500,500);
window.setObjectName("window");
window.setStyleSheet("background-color: rgba(0,0,128,128); ");
// Content window
NormalWidget content(&window);
content.setObjectName("content");
content.resize(400, 400);
content.move(0,0);
content.setStyleSheet("background-color: rgba(128,0,0,128);");
TransparentWidget custom(&window);
custom.setObjectName("custom");
custom.resize(500, 200);
custom.setStyleSheet("background-color:rgba(0,128,0,128);");
window.show();
return a.exec();
}
transparentwidget.hpp
#ifndef TRANSPARENTWIDGET_H
#define TRANSPARENTWIDGET_H
#include <QWidget>
#include <QStyleOption>
#include <QPainter>
#include <QDebug>
#include <QEvent>
// This widget shall be transparent in some parts
class TransparentWidget : public QWidget
{
Q_OBJECT
public:
explicit TransparentWidget(QWidget *parent = 0): QWidget(parent)
{
// Start of solution with WA_TransparentForMouseEvents (not working)
setAttribute(Qt::WA_TransparentForMouseEvents);
// end solution with WA_TransparentForMouseEvents
}
~TransparentWidget(){}
protected:
QRect opaqueRect = QRect(0,0,400,100);
void paintEvent(QPaintEvent *)
{
// Solution with setMask, not working
QRegion reg(opaqueRect);
setMask(reg);
// end of setMask solution
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
bool event(QEvent *event)
{
// Starting of solution with event propagation (not working)
if (event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* e = static_cast<QMouseEvent*>(event);
if (e && !opaqueRect.contains(e->pos()) return false;
}
// end solution with event propagation.
if (event->type() == QEvent::MouseButtonPress) qDebug() << "Press: " << objectName();
else if(event->type() == QEvent::MouseButtonRelease) qDebug() << "Release: " << objectName();
return QWidget::event(event);
}
};
#endif
normalwidget.hpp
#ifndef NORMALWIDGET_H
#define NORMALWIDGET_H
#include <QWidget>
#include <QStyleOption>
#include <QPainter>
#include <QDebug>
#include <QEvent>
// Widgets that are not event-transparent
class NormalWidget : public QWidget
{
Q_OBJECT
public:
explicit NormalWidget(QWidget *parent = 0): QWidget(parent){}
~NormalWidget(){}
protected:
void paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
bool event(QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) qDebug() << "Press: " << objectName();
else if(event->type() == QEvent::MouseButtonRelease) qDebug() << "Release: " << objectName();
}
};
#endif // NORMALWIDGET_H
答案 0 :(得分:0)
就像文档说的那样:
启用后,此属性将禁用鼠标事件的传递 小部件和其子级。
解决方案是忽略TransparentWidget::event()
内的所有鼠标事件。如果对TransparentWidget
的孩子进行鼠标事件,则该事件将由孩子使用,否则将被传递给TransparentWidget
的父母:
bool TransparentWidget::event(QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonRelease ||
event->type() == QEvent::MouseButtonRelease)
return false;
else
return QWidget::event(event);
}