Как не вызывать состояние наведения, когда мышь находится в углу круглого QPushButton? - PullRequest
3 голосов
/ 30 марта 2019

У меня есть QPushButton с закругленными углами:

enter image description here

Теперь я хочу изменить стиль кнопки, когда на нее движется мышь:

enter image description here

Я использовал setStyleSheet из QPushButton:

QPushButton{
    width:100px;
    height:80px;
    border-radius:40px;
    border: 1px solid #ffffff;
}
QPushButton:hover{
    background: red;    
}

Но не четыре угла:

enter image description here

как показано на третьем изображении, курсор указывает на правый нижний угол кнопки, но также вызывает состояние наведения кнопки. Есть ли простой способ предотвратить такое поведение?

1 Ответ

0 голосов
/ 31 марта 2019

Может быть, , существует более простое решение этого вопроса, но я только что попробовал, и оказалось, что реализация всего поведения при наведении вручную кажется единственным действительно действующим способом.

Как правило, все дело в проверке того, что координаты мыши принадлежат эллипсу (вы можете попробовать другие геометрические соображения).

Что-то, что не работает:

ui->myButton->installEventFilter(this);

//----------------------------------------

bool SomeWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverMove)
    {
        QHoverEvent* hoverEvent = static_cast<QHoverEvent *>(event);
        QWidget* target = qobject_cast<QWidget *>(obj);
        qreal a = target->width() / 2;
        qreal b = target->height() / 2;
        qreal x = hoverEvent->posF().x() - a;
        qreal y = hoverEvent->posF().y() - b;

        double val = (x / a) * (x / a) + (y / b) * (y / b);
        bool isInside = val <= 1;
        if (!isInside)
            return true;
        else
            return QObject::eventFilter(obj, event);
    } 
        return QObject::eventFilter(obj, event);
}

С SomeWidget, в котором установлены кнопка и фильтр событий, это выглядело многообещающе, но работает ужасно = (

То, что работает в качестве доказательства концепции:

CustomButton::CustomButton(QWidget *parent)
    : QPushButton(parent)
{
    setProperty("my_hover", "not_hovered");
}

void CustomButton::mouseMoveEvent(QMouseEvent *event)
{
    qreal a = width() / 2;
    qreal b = height() / 2;
    qreal x = event->pos().x() - a;
    qreal y = event->pos().y() - b;

    double val = (x / a) * (x / a) + (y / b) * (y / b);
    bool isInside = val <= 1;
    setProperty("my_hover", isInside ? "hovered" : "not_hovered" );
    style()->unpolish(this);
    style()->polish(this);
}

Подклассы QPushButton работали лучше (приведенный выше код представляет собой читабельный образец, вы, конечно, можете его улучшить). При реализации он предоставляет классу кнопки собственное свойство, которое можно использовать так:

QPushButton[my_hover="hovered"]
{
  background: red;    
}

Чтобы сделать его идеальным решением, вам, вероятно, придется позаботиться и о mouseLeaveEvent, чтобы избежать случайных сбоев. Кроме того, это свойство, вероятно, можно сделать логическим, если оно работает с вашим Qt.

AFAIK, это единственный верный способ реализовать желаемое поведение, которое вы описали.

...