Щелчок мыши по всплывающей подсказке, отображаемой в QSpinBox :: validate, вызывает сбой - PullRequest
0 голосов
/ 13 июня 2019

У меня есть собственный класс SpinBox, который расширяет функциональность QSpinBox.Я пытаюсь показать всплывающую подсказку, когда ввод правильный, то есть показать всплывающую подсказку QSpinBox::validate(QString &text, int &pos).Но когда я щелкаю мышью по всплывающей подсказке, программа вылетает.Сбой происходит в QApplicationPrivate::notifyActiveWindowChange(QWindow *previous), похоже, Qt пытается установить QTipLabel (который уже был уничтожен) в качестве активного окна.

Вот минимальный код для воспроизведения аварии:

// spinbox.h
#include <QSpinBox>
#include <QToolTip>

class SpinBox : public QSpinBox
{
    Q_OBJECT

public:
    explicit SpinBox(QWidget *parent = nullptr)
        : QSpinBox(parent)
    {}
    ~SpinBox() override = default;

    QValidator::State validate(QString &input, int &pos) const override
    {
        Q_UNUSED(pos);
        int x = input.toInt();
        auto mn = minimum();
        auto mx = maximum();
        if(x >= mn && x <= mx)
        {
            QToolTip::showText(mapToGlobal({0, 0}), QString("Your value fits the range!!!"));
            return QValidator::State::Acceptable;
        }
        else
        {
            QToolTip::hideText();
        }
        return QValidator::State::Invalid;
    }
};

// constructor of the default mainwindow created by qt creator
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    Ui::MainWindow ui;
    ui.setupUi(this);

    auto spin_box = new SpinBox(this);
    spin_box->setRange(1, 200);
}

Вот рисунок, который иллюстрирует сбой: GIF

Заранее спасибо!

UPD. Я обнаружил, что после нажатия наВо всплывающей подсказке окно qtooltip_labelWindow получает фокус.enter image description here

UPD2. Я еще не нашел причину сбоя, но обходной путь, который помогает мне, - установить следующий фильтр событий в qApp:

bool eventFilter(QObject* obj, QEvent* e) override
{
    if(obj->objectName().contains("tooltip") && e->type() == QEvent::FocusIn)
    {
      if (auto window = qobject_cast<QWindow*>(obj))
          window->show();
    }
    return QObject::eventFilter(obj, e);
}
...