如何禁用鼠标事件到小部件但不是Qt的子节点?

Shu*_*han 11 qt parent-child transparent mouseevent

从最近两天开始,我正在搜索并找出一种方法将鼠标事件传递给窗口小部件后面的窗口小部件,该窗口小部件用作其子容器的容器/父窗口.我知道有一种方法可以使小部件对于像这样的鼠标事件透明:

QWidget w;
w.setAttribute( Qt::WA_TransparentForMouseEvents );
Run Code Online (Sandbox Code Playgroud)

但这也禁止向其孩子发送鼠标事件!实际上我希望前面小部件的子节点和前面小部件后面的小部件响应鼠标事件.

Qt :: WA_TransparentForMouseEvents:启用后,此属性将禁用向窗口小部件及其子窗口传递鼠标事件.鼠标事件被传递到其他窗口小部件,就好像窗口小部件及其子窗口不存在于窗口小部件层次结构中一样; 鼠标点击和其他事件有效地"通过"他们.默认情况下禁用此属性.

如果您对如何使鼠标事件透明,而不是它的孩子有任何想法,那么请分享!

Shu*_*han 12

最后我找到了一个解决方案:)这个答案适用于那些寻求解决此类问题的人. 关键:解决方案的关键是QWidget :: setMask(const QRegion®ion)

http://doc.qt.io/qt-5/qwidget.html#setMask-2

http://qt-project.org/doc/qt-4.8/qwidget.html#setMask

我在这里找到了解决方案:http://www.qtcentre.org/archive/index.php/t-3033.html

QRegion reg(frameGeometry());
reg -= QRegion(geometry());
reg += childrenRegion();
setMask(reg);
Run Code Online (Sandbox Code Playgroud)

现在,前部窗口小部件的子窗口和前端窗口小部件后面的窗口小部件会根据需要响应鼠标事件!

请记住,只要重新调整前面的小部件大小以重新计算面具的几何形状,就需要再次调用这些行!(在我的情况下,它不是必需的,但它适用于那些可能需要的人).

void someWidget::resizeEvent(QResizeEvent *e){
  QWidget::resizeEvent(e);
  QRegion reg(frameGeometry());
  reg-=QRegion(geometry()); 
  reg+=childrenRegion();
  setMask(reg);
}
Run Code Online (Sandbox Code Playgroud)