带有自定义项目的 QListView => 鼠标事件被传播

Posted

技术标签:

【中文标题】带有自定义项目的 QListView => 鼠标事件被传播【英文标题】:QListView with custom item => mouse events are propagated 【发布时间】:2014-10-10 09:39:06 【问题描述】:

我想将 QListView 与包含 QSlider 和 QSpinBox 小部件的自定义小部件一起使用。 我成功地使用显示自定义小部件的新自定义项委托创建 QListView,但鼠标事件不会传播到自定义小部件。

不能滑动 QSlider 或更改 QSpinBox 的值。用户无法与项目交互。

我是 Qt 新手,我猜这是因为自定义小部件不是列表视图的子项。我试图将小部件与列表视图相关联(在项目委托构造函数中),但这不起作用。

我还尝试使用 QWidget::event() 函数将项目委托的事件传播到小部件,但这不起作用。

有人有想法吗?

这是自定义小部件:

这是显示自定义小部件的 QListView:

这是我的自定义项目委托的代码:

#include <QPainter>
#include "layeritemwidgetdelegate.h"
#include "../../libs/debug/debug.h"

LayerItemWidgetDelegate::LayerItemWidgetDelegate( QObject *ptParent ) :
    QItemDelegate( ptParent ),
    m_ptItemWidget( new LayerItemWidget() )



LayerItemWidgetDelegate::~LayerItemWidgetDelegate()

    delete m_ptItemWidget;


void LayerItemWidgetDelegate::paint( QPainter *ptPainter, const QStyleOptionViewItem &tOption, const QModelIndex &tIndex ) const

    QPalette tPalette;

    //  Resize the item widget
    m_ptItemWidget->resize( tOption.rect.size() );

    // Change the background color of the widget if it is selected.
    if( QStyle::State_Selected == ( tOption.state & QStyle::State_Selected ) )
        tPalette.setBrush( QPalette::Window, QBrush( QColor( Qt::lightGray ) ) );
    else
        tPalette.setBrush( QPalette::Window, QBrush( QColor( Qt::transparent ) ) );
    m_ptItemWidget->setPalette( tPalette );

    //  Paint the widget
    ptPainter->save();
    ptPainter->translate( tOption.rect.topLeft() );
    m_ptItemWidget->render( ptPainter );
    ptPainter->restore();


QSize LayerItemWidgetDelegate::sizeHint(const QStyleOptionViewItem &tOption, const QModelIndex &tIndex) const

    Q_UNUSED( tOption )
    Q_UNUSED( tIndex )
    return QSize( m_ptItemWidget->minimumWidth(), m_ptItemWidget->height() );


bool LayerItemWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)

    m_ptItemWidget->propagateEvent(event);
    m_ptItemWidget->setEnabled( true );
    DEBUG_MESSAGE( "EVENT" );

【问题讨论】:

【参考方案1】:

您应该阅读有关setItemWidget 方法的文档。您可以将小部件设置为仅显示一些数据,而不是用于与这些小部件交互。

可能的解决方法(应该如何完成,但这项任务需要大量调整):

    实现一个将绘制必要控件的委托(或使用QPixmap::grabWidget 并缓存您的小部件视图) 跟踪鼠标事件 当鼠标悬停在某个 QModelIndex 上时 - 然后为该项目创建一个编辑器。 跟踪编辑器事件,当鼠标离开时 - 隐藏编辑器并提交数据

但在你的情况下,我相信你应该考虑重新设计你的想法(如果你没有太多的项目):

    使用垂直布局创建您自己的小部件 将小部件放在那里 处理模型事件(...利润!)

备注:项目视图小部件旨在显示大量数据,它们并非旨在进行复杂的交互。

【讨论】:

由于关于 setItemWidget 的文档,我使用了带委托的 QListView “如果您想显示自定义动态内容或实现自定义编辑器小部件,请改用 QListView 和子类 QItemDelegate。”我>。但我必须实现 workdaroung 因为这是 QListWidget 所做的(我已经检查了源代码)。我不会只显示上百个数据。

以上是关于带有自定义项目的 QListView => 鼠标事件被传播的主要内容,如果未能解决你的问题,请参考以下文章

用于自定义项目的 C DLL

在 Qt C++ 中的自定义项委托上绘制文本时的性能问题

意图选择器屏幕中自定义项目的回调

带有自定义项的 QTreeView

带有自定义项的 GWT 组合框

带有 ListView 自定义项的 Android 小部件