qtpropertybrowser自定义弹窗消失问题

qtpropertybrowser是Qt属性树控件,编辑时可以使用内置的编辑控件,例如QSpinBox、QLineEdit等。当我们使用自定义弹出窗口(例如MyEditor窗口类,该窗口由多个控件组成,且窗口高度大于默认的QTreeWidgetItem高度),鼠标在弹出窗口内点击非焦点输入控件(例如QLineEdit)时,窗口会消失,似乎鼠标事件透过了窗体,进入窗体下方的QTreeWidgetItem上了,然而这并不是我们想要的结果。为了解决这个问题,我们需要修改qtpropertybrowser工程。
错误演示
qtpropertybrowser自定义弹窗消失问题_第1张图片

正确效果
qtpropertybrowser自定义弹窗消失问题_第2张图片

解决方案

  1. 修改为如下代码:当鼠标点击位置在弹出窗口中时,也禁止窗口消失(步骤1)
bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::FocusOut) {
        QFocusEvent *fe = static_cast(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);
}
  1. 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(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);	// 安装事件过滤器

你可能感兴趣的:(Qt探索之旅,qt,c++)