如何创建qt标签悬停效果?

时间:2016-11-21 20:45:35

标签: c++ qt

我必须在Qt标签上使用悬停事件,但我找不到有关它的信息。 我尝试使用类似ui->label->setText("<a>ads</a>")onLinkHovered的内容,但这不正确。

我必须在悬停时更改文字。

4 个答案:

答案 0 :(得分:4)

最灵活的解决方案是创建自己的继承自QLabel的小部件。这样,您可以覆盖 enterEvent leaveEvent @Jeremy,@ Moe正在撰写有关受保护的内容。作为这些方法实现的一部分,您可以相应地更改文本或装饰。例如:

class CustomLabel : public QLabel
{
    Q_OBJECT
public:
    CustomLabel(QWidget* parent = nullptr) : QLabel(parent){ }

protected:
    void enterEvent(QEvent *ev) override
    {
        setStyleSheet("QLabel { background-color : blue; }");
    }

    void leaveEvent(QEvent *ev) override
    {
        setStyleSheet("QLabel { background-color : green; }");
    }
};

另一种方法,但不太灵活的是为标签文本中指定的链接标记设置href属性。这样文本将被视为实际链接,您可以使用linkHovered信号进行连接。例如:

ui->label->setText("<a href='www.google.com'>link</a>");
connect(ui->label, &QLabel::linkHovered, this, [this](const QString&)
{
    // do smth with the widget/text
});

但是,请注意,这样您只能对悬停事件进行修改。 因此,如果您需要将标签恢复到原始状态,那么第一个选项是可行的方法。

答案 1 :(得分:0)

利用enterEvent的{​​{1}}和leaveEvent

创建QLabel的子类,例如:

QLabel

并覆盖class MyLabel : public QLabel { public: MyLabel(); MyLabel(char* text, MainWindow* w) : QLabel(text, w) { } void enterEvent(QEvent *event); void leaveEvent(QEvent *event); }; enterEvent,如下所示:

leaveEvent

您现在可以像这样创建此类的实例:

void MyLabel::enterEvent(QEvent *event) {

    qDebug() << "Entered!";
    // Change your text here
}

void MyLabel::leaveEvent(QEvent *event) {

    qDebug() << "Left!";
}

答案 2 :(得分:0)

如果要确定鼠标是否悬停在QLabel中的文本上,可以使用

void mouseMoveEvent(QMouseEvent* event);

并在其中检查鼠标光标是否在文本的边界矩形内。

void PressLabel::mouseMoveEvent(QMouseEvent* event) {
    QRect bRect = getTextComponentRectangle();
    m_mouseCoord = event->pos();
    if(bRect.contains(event->pos())) {
        // Mouse pointer over text.
    } else {
        // Mouse pointer outside text.
    }
    QLabel::mouseMoveEvent(event);
}

为小部件打开鼠标跟踪,以使mouseMoveEvent也在未按下鼠标按钮时发生。

setMouseTracking(true);

最后是执行文本边界矩形计算的函数。下面的代码也考虑了一些意外情况。 我在Qt 5.9.1上尝试过

有关否定情况下有效缩进的计算,请参见http://doc.qt.io/archives/qt-4.8/qlabel.html#indent-prop

QRect PressLabel::getTextComponentRectangle() const {
     if(frameWidth() < 0) {
        throw std::runtime_error("Negative frame width.");
    }
    int effectiveIndent = indent();
    int trueMargin = margin();
    if(effectiveIndent < 0) {
        if(frameWidth() == 0 || margin() > 0) { // (1)
            effectiveIndent = 0;
        } else if(frameWidth() > 0) {
            QFontMetrics fm(font());
            effectiveIndent = fm.width(QChar('x')) / 2;
        }
        if(frameWidth() > 0 && margin() < 0) { // (2)
            trueMargin = 0;
        }
    }

    QFontMetrics fm(font());
    QRect bRect = fm.boundingRect(text());
    bRect.setWidth(fm.width(text()));

    int indentOffset = effectiveIndent + trueMargin + frameWidth();
    int offsetX = 0;
    int offsetY = 0;
    if(alignment() & Qt::AlignHCenter) {
        offsetX = rect().width() / 2 - bRect.width() / 2;
    } else if(alignment() & Qt::AlignRight) {
        offsetX = rect().width() - bRect.width() - indentOffset;
    } else if(alignment() & Qt::AlignJustify) {
        offsetX = trueMargin + frameWidth();
    } else if(alignment() & Qt::AlignLeft) {
        offsetX = indentOffset;
    }
    if(alignment() & Qt::AlignVCenter) {
        offsetY = rect().height() / 2 - bRect.height() / 2;
    } else if(alignment() & Qt::AlignBottom) {
        offsetY = rect().height() - bRect.height() - indentOffset;
    } else if(alignment() & Qt::AlignTop) {
        offsetY = indentOffset;
    }

    bRect.moveTopLeft(rect().topLeft());
    bRect.setX(bRect.x() + offsetX);
    bRect.setWidth(bRect.width() + offsetX);
    bRect.setY(bRect.y() + offsetY);
    bRect.setHeight(bRect.height() + offsetY);

    return bRect;
}

意外情况:

(1)对于缩进<0和margin> 0,有效缩进为0,而不是width('x')/ 2,因为它打算用于负缩进。

(2)对于缩进<0和margin <0,真正的margin为0,不求和以求得偏移。

答案 3 :(得分:0)

我发现您也可以通过样式表来实现这一点。

self.label = QtWidgets.QLabel("Toast")
self.label.setStyleSheet("QLabel{color: white;} QLabel:hover {color: blue;}")