qtpropertybrowser是Qt属性树控件,编辑时可以使用内置的编辑控件,例如QSpinBox、QLineEdit等。当我们使用自定义弹出窗口(例如MyEditor窗口类,该窗口由多个控件组成,且窗口高度大于默认的QTreeWidgetItem高度),鼠标在弹出窗口内点击非焦点输入控件(例如QLineEdit)时,窗口会消失,似乎鼠标事件透过了窗体,进入窗体下方的QTreeWidgetItem上了,然而这并不是我们想要的结果。为了解决这个问题,我们需要修改qtpropertybrowser工程。
错误演示
正确效果
解决方案
- 修改为如下代码:当鼠标点击位置在弹出窗口中时,也禁止窗口消失(步骤1)
bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::FocusOut) {
QFocusEvent *fe = static_cast<QFocusEvent *>(event);
if (fe->reason() == Qt::ActiveWindowFocusReason)
return false;
// 处理鼠标点击弹出窗口非焦点控件时,弹出窗口消失问题(步骤1)
if (m_editedItem != nullptr && m_editedWidget != nullptr)
{
QPoint pos = m_editorPrivate->treeWidget()->viewport()->mapFromGlobal(QCursor::pos());
if (m_editedWidget->geometry().contains(pos))
return false;
}
}
return QItemDelegate::eventFilter(object, event);
}
- QtPropertyEditorView中添加eventFilter函数处理,需要在QtPropertyEditorView的构造函数处安装事件过滤器(步骤2)
bool QtPropertyEditorView::eventFilter(QObject *object, QEvent *event)
{
if (object == viewport())
{
// 处理鼠标点击弹出窗口非焦点控件时,弹出窗口消失问题(步骤2)
if (event->type() == QEvent::MouseButtonPress/* || event->type() == QEvent::MouseButtonRelease*/)
{// event->type() == QEvent::MouseButtonRelease注释掉和放开都可以(因为没有了Press,自然就没有了Release的产生)
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
QTreeWidgetItem *item = itemAt(mouseEvent->pos());
if (item)
{
if (m_editorPrivate->editedItem() != nullptr && m_editorPrivate->editedWidget() != nullptr)
{
QWidget *widget = m_editorPrivate->editedWidget();
if (widget->geometry().contains(mouseEvent->pos()))
return true;
}
}
}
}
return QTreeWidget::eventFilter(object, event);
}
// 构造函数中添加如下代码:
viewport()->installEventFilter(this); // 安装事件过滤器
版权声明:本文为qq_40945965原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。