效果图
概述
整个界面的布局介绍请看这篇博客 想要的到这种自由选择中的Item效果,需要使用到Model-view的思想,每个item中都要存放一个标志位,用在Paint
函数去判断是否绘制为按下的状态。 每次item被点击时,更新标志位,并刷新视图,从而实现点击后变色的效果。
部分代码
void CustomDelegate :: paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
{ int radius = 10 ; painter-> setRenderHint ( QPainter:: Antialiasing) ; painter-> setPen ( Qt:: NoPen) ; if ( index. model ( ) -> data ( index, Qt:: UserRole) . toBool ( ) ) { painter-> setBrush ( QColor ( "#d9d9d9" ) ) ; painter-> drawRoundedRect ( option. rect. adjusted ( 2 , 2 , - 2 , - 2 ) , radius, radius) ; } if ( option. state & QStyle:: State_MouseOver || option. state & QStyle:: State_Selected) { painter-> setBrush ( QColor ( "#e4e4e4" ) ) ; painter-> drawRoundedRect ( option. rect. adjusted ( 2 , 2 , - 2 , - 2 ) , radius, radius) ; } if ( QStyle:: State_HasFocus & option. state) { } QStyledItemDelegate :: paint ( painter, option, index) ;
}
重写editorEvent
函数,这个的目的是忽悠掉qt的这几个事件,这样就不会绘制qt的默认的焦点框了
bool CustomDelegate :: editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index)
{ if ( event-> type ( ) == QEvent:: MouseMove || event-> type ( ) == QEvent:: MouseButtonPress || event-> type ( ) == QEvent:: MouseButtonDblClick) { return true ; } return QStyledItemDelegate :: editorEvent ( event, model, option, index) ;
}
在listview中,设置样式,不让悬浮出现自带的样式
setStyleSheet ( "QListView::item:hover { background: transparent; border: none; }" ) ;
connect ( m_listView, & QListView:: clicked, [ & ] ( const QModelIndex & index) { bool isChecked = index. model ( ) -> data ( index, Qt:: UserRole) . toBool ( ) ; m_listView-> model ( ) -> setData ( index, ! isChecked, Qt:: UserRole) ; m_listView-> update ( ) ; } ) ;
QVariant IconTextModel :: data ( const QModelIndex & index, int role) const
{ if ( ! index. isValid ( ) || index. row ( ) >= m_data. count ( ) ) return QVariant ( ) ; switch ( role) { case Qt:: DecorationRole: return QIcon ( m_data. at ( index. row ( ) ) . m_icon) ; case Qt:: DisplayRole: return m_data. at ( index. row ( ) ) . m_name; case Qt:: UserRole: return m_data. at ( index. row ( ) ) . m_isChecked; default : return QVariant ( ) ; }
}
bool IconTextModel :: setData ( const QModelIndex & index, const QVariant & value, int role)
{ if ( index. isValid ( ) && role == Qt:: UserRole) { m_data[ index. row ( ) ] . m_isChecked = value. toBool ( ) ; emit dataChanged ( index, index) ; } return true ;
}
总结
知识理应共享,源码在此。 这个示例中的功能点,主要在于绘制函数的实现,要考虑怎么把原有qt的绘制屏蔽掉,关于数据处理的部分很简单