我正在创建一个应用程序,以可视化方式表示节点和将它们连接在一起的线。节点和线都由自定义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();
}

09-05 02:42