我正在创建一个应用程序,以可视化方式表示节点和将它们连接在一起的线。节点和线都由自定义QWidget,WidgetNode和WidgetLine表示。
我已经将WidgetLine实现为透明的窗口小部件,该窗口小部件足够大以包含线条的起点和终点,并且具有自定义函数来绘制线条本身。
我希望这样,如果用户单击该行或该行旁边,则WidgetLine会获得焦点,但是如果他们单击的位置离该行较远(但仍在WidgetLine的几何覆盖的矩形区域上),则该单击将被完全忽略由WidgetLine传递给下面的小部件。
我首先尝试使用WidgetLine上的自定义focusInEvent()
函数来执行此操作,但发现鼠标单击没有在下面传播。然后,我尝试将焦点策略设置为Qt::NoFocus
并使用自定义的mousePressEvent()
使用setFocus()
在适当的时候手动设置焦点,但是即使我在ignore()
上调用,鼠标事件仍不会传播到上方的小部件他们。
最后,我尝试使用此事件过滤器功能安装事件过滤器以拒绝鼠标事件
bool WidgetLineFilter::eventFilter(QObject* object, QEvent* event)
{
assert(object == mCord);
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent* e = dynamic_cast<QMouseEvent*>(event);
assert(e);
if (e)
{
QPoint mouseRelativeToParent = mCord->mapToParent(e->pos());
// calculate distance of mouse click to patch cord
QLineF line(mCord->line());
float distance = distanceFromPointToLine(QVector2D(line.p1()), QVector2D(line.p2()), QVector2D(mouseRelativeToParent));
qDebug() << distance;
const float distanceThreshold = 2.f;
if (distance < distanceThreshold)
{
qDebug() << "consuming mouse click for focus";
mCord->setFocus(Qt::MouseFocusReason);
return true;
}
else{
qDebug() << "mousepressevent too far for focus";
return QObject::eventFilter(object, event);
}
}
}
return false;
}
但这仍然不会将鼠标事件传播到“ mousepressevent too too focus for focus”情况下的父事件。我也尝试过从此处返回false和true,并在
ignore
上调用e
,但是下面的小部件没有收到点击。(注意,上述方法在WidgetLine仅在正确的时间获得焦点的意义上起作用,只是下面的窗口小部件在没有获得焦点时才接收新闻事件。)
有想法该怎么解决这个吗?
最佳答案
将鼠标pos存储在全局变量中。让所有小部件都具有如下输入/离开事件,并在运行功能时使用该事件来检查您所在/附近的小部件。
void QGLWidget::enterEvent(QEvent *)
{
setFocus();
}
void QGLWidget::leaveEvent(QEvent *)
{
clearFocus();
}