我有一个自定义的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会获得焦点。
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);
}