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

时间:2014-10-10 09:39:07

标签: qt listview qitemdelegate

我想将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 个答案:

答案 0 :(得分:0)

您应该阅读有关setItemWidget方法的文档。您可以仅设置窗口小部件以显示某些数据,而不是与此窗口小部件进行交互。

可能的解决方法(如何完成,但此任务需要进行大量调整):

  1. 实现将绘制必要控件的委托(或使用QPixmap::grabWidget并缓存窗口小部件视图)
  2. 跟踪鼠标事件
  3. 当鼠标悬停某些QModelIndex时 - 然后为此项目创建一个编辑器。
  4. 跟踪编辑器事件,当鼠标离开时 - 隐藏编辑器并提交数据
  5. 但在你的情况下,我相信你应该考虑重新设计你的想法(如果你没有太多项目):

    1. 使用垂直布局创建自己的小部件
    2. 将小部件放在那里
    3. 处理模型事件(......利润!)
    4. 备注:项目视图窗口小部件旨在显示大量数据,而不是用于执行复杂交互。