У меня есть собственный класс 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);
}
Вот рисунок, который иллюстрирует сбой:
Заранее спасибо!
UPD. Я обнаружил, что после нажатия наВо всплывающей подсказке окно qtooltip_labelWindow получает фокус.
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);
}