Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Strange border appearing when hovering over Widgets in a QGraphicsScene



  • Hi all,

    I've got this QGraphicsProxyWidget which is composed of QFrames and QLabels. A stylesheet defines the appearance of the item. Everything works fine, except for a gray border which appears around some labels whenever the mouse passes over them. I unfortunately don't have much useful code to show (not sure posting the whole class would be relevant), and can't send screenshots of the problem from this computer... Not a showstopper for the moment, but a bit annoying and I can't find any clues about what causes this. Any ideas?

    Thx in advance!

    EDIT:

    Wow! I've had no clue about this for the last three months and partially found a solution in about 3 minutes about posting this... Still needs some clarification tough.

    I simply overrided the hoverEnterEvent, hoverLeaveEvent and hoverMoveEvent.

    @void NodeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
    {
    Q_UNUSED(event)
    qDebug() << "hoverEnterEvent on NodeItem";
    }

    void NodeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
    {
    Q_UNUSED(event)
    qDebug() << "hoverLeaveEvent on NodeItem";
    }

    void NodeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
    {
    Q_UNUSED(event)
    qDebug() << "hoverMoveEvent on NodeItem";
    }@

    It seems that my QGraphicsProxyWidget ignores setAcceptHoverEvents(false), as debug messages always print.

    The problem reappears by adding

    @QGraphicsProxyWidget::hover{Enter/Leave/Move}Event(event);@

    in the previous functions.

    So a clearer question would be: why is setAcceptHoverEvents(false) ignored? Are empty reimplementations of hover events an acceptable solution?


  • Moderators

    i guess the border most probably comes from a definition in your stylesheet.



  • Well here's a bit more about how the Item is constructed. It's a node composed of a header, a list of input connectors and a list of output connectors.

    @NodeItem::NodeItem(AbstractNode *node, QGraphicsItem *parent)
    : QGraphicsProxyWidget(parent),
    m_instance(node),
    m_zvalue(0)
    {
    setCacheMode(DeviceCoordinateCache);
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
    setZValue(m_zvalue);
    setAcceptHoverEvents(false); // Doesn't seem to do anything

    QFrame *m_nodeWidget = new QFrame();
    m_nodeWidget->setObjectName("NodeItem");
    
    QLabel *nodeHeader = new QLabel(m_instance->objectName());
    nodeHeader->setObjectName("NodeHeaderLabel");
    
    QFrame *innerFrame = new QFrame();
    innerFrame->setObjectName("NodeInnerFrame");
    
    QFrame *contentFrame = new QFrame();
    contentFrame->setObjectName("NodeContentFrame");
    
    QHBoxLayout *connectorsLayout = new QHBoxLayout();
    QVBoxLayout *inputsLayout = new QVBoxLayout();
    QVBoxLayout *outputsLayout = new QVBoxLayout();
    connectorsLayout->addLayout(inputsLayout);
    connectorsLayout->addLayout(outputsLayout);
    contentFrame->setLayout(connectorsLayout);
    
    QVBoxLayout *contentLayout = new QVBoxLayout();
    contentLayout->addWidget(nodeHeader);
    contentLayout->addWidget(contentFrame);
    innerFrame->setLayout(contentLayout);
    
    QVBoxLayout *nodeLayout = new QVBoxLayout();
    nodeLayout->addWidget(innerFrame);
    m_nodeWidget->setLayout(nodeLayout);
    
    inputsLayout->setMargin(0);
    outputsLayout->setMargin(0);
    connectorsLayout->setMargin(0);
    contentLayout->setMargin(0);
    nodeLayout->setMargin(0);
    
    /* Add input ports */
    input_map_t ins = m_instance->inputs();
    for (input_map_t::iterator it = ins.begin(); it != ins.end(); ++it) {
        addConnector(inputsLayout, it.key(), NodeConnectorItem::Input);
    }
    
    /* Add output ports */
    output_map_t outs = m_instance->outputs();
    for (output_map_t::iterator it = outs.begin(); it != outs.end(); ++it) {
        addConnector(outputsLayout, it.key(), NodeConnectorItem::Output);
    }
    
    setToolTip(m_instance->getDescription());
    setWidget(m_nodeWidget);
    

    }

    NodeConnectorItem* NodeItem::addConnector(QBoxLayout *layout, const QString &name, NodeConnectorItem::ConnectorType connectorType)
    {
    NodeConnectorItem *connector = 0;
    QLabel *label = new QLabel(name);

    if (connectorType == NodeConnectorItem::Input) {
        label->setObjectName("NodeInput");
        layout->addWidget(label, 0, Qt::AlignLeft);
    } else {
        label->setObjectName("NodeOutput");
        layout->addWidget(label, 0, Qt::AlignRight);
    }
    
    connector = new NodeConnectorItem(name, connectorType, label, this);
    m_connectors.append(connector);
    
    return connector;
    

    }

    // Seems like hover events are always enabled and not propagating the event by calling base class event func fixes the problem
    void NodeItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event){}
    void NodeItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event){}
    void NodeItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event){}
    @

    And here's the stylesheet, which is pretty simple.

    @#NodeItem {
    background-color: rgba(0,0,0,0);
    border-radius: 4px;
    margin: 0px;
    padding: 0px;
    }

    #NodeInnerFrame {
    background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0.25 rgba(50, 50, 50, 192), stop:1 rgba(160, 160, 160, 192));
    border-radius: 4px;
    margin: 0px;
    padding: 0px;
    }

    #NodeContentFrame {
    background-color: rgba(0,0,0,0);
    padding: 4px;
    margin: 4px;
    }

    #NodeHeaderLabel {
    background-color: rgba(224,224,224,255);
    color: black;
    border-radius: 2px;
    font: 10px;
    font-weight: bold;
    padding: 2px;
    }

    #NodeInput {
    background-color: rgba(0,0,0,0);
    color: white;
    }

    #NodeOutput {
    background-color: rgba(0,0,0,0);
    color: white;
    }@


Log in to reply