Qt实现复杂列表  
 界面效果 layeritemdelegate.h layeritemdelegate.cpp layertablemodel.h layertablemodel.cpp layertableview.h layertableview.cpp mainwindow.h mainwindow.cpp   
  
 
 界面效果  
 
 layeritemdelegate.h  
# ifndef  LAYERITEMDELEGATE_H  
# define  LAYERITEMDELEGATE_H  
# include  <QStyledItemDelegate>  
# include  <QLineEdit>  
# include  <QDebug>  
# include  <QPainter>  
class  LayerItemDelegate  :  public  QStyledItemDelegate  
{ 
    Q_OBJECT
public : 
    LayerItemDelegate ( QObject * parent= 0 ) ; 
    ~ LayerItemDelegate ( ) ; 
    void  paint ( QPainter *  painter,  const  QStyleOptionViewItem &  option,  const  QModelIndex &  index)  const ; 
    QWidget * createEditor ( QWidget * parent,  const  QStyleOptionViewItem & option, 
        const  QModelIndex & index)  const ; 
    bool  editorEvent ( QEvent *  event, 
        QAbstractItemModel *  model, 
        const  QStyleOptionViewItem &  option, 
        const  QModelIndex &  index) ; 
    void  setEditorData ( QWidget * editor,  const  QModelIndex & index)  const ; 
    void  setModelData ( QWidget * editor,  QAbstractItemModel * model, 
        const  QModelIndex & index)  const ; 
    void  updateEditorGeometry ( QWidget * editor, 
        const  QStyleOptionViewItem & option,  const  QModelIndex & index)  const ; 
private : 
    QPixmap m_gridPixmap; 
} ; 
# endif   
  
 layeritemdelegate.cpp  
# include  "layeritemdelegate.h"  
LayerItemDelegate :: LayerItemDelegate ( QObject * parent) 
    :  QStyledItemDelegate ( parent) 
{ 
    QImage gridImage ( 200 ,  200 ,  QImage:: Format_RGB32) ; 
    QRgb grey =  QColor ( 204 ,  204 ,  204 ) . rgb ( ) ; 
    QRgb white =  QColor ( 255 ,  255 ,  255 ) . rgb ( ) ; 
    for  ( int  i =  0 ;  i <  200 ;  i++ ) 
    for  ( int  j =  0 ;  j <  200 ;  j++ ) 
    { 
        int  tmpX =  i %  10 ; 
        int  tmpY =  j %  10 ; 
        if  ( tmpX <  5 ) 
        { 
            gridImage. setPixel ( i,  j,  tmpY <  5  ?  grey :  white) ; 
        } 
        else 
        { 
            gridImage. setPixel ( i,  j,  tmpY <  5  ?  white :  grey) ; 
        } 
    } 
    m_gridPixmap =  QPixmap :: fromImage ( gridImage) ; 
} 
LayerItemDelegate :: ~ LayerItemDelegate ( ) 
{ 
} 
void  LayerItemDelegate :: paint ( QPainter *  painter,  const  QStyleOptionViewItem &  option,  const  QModelIndex &  index)  const 
{ 
    if  ( index. column ( )  ==  1 )  
    { 
        if  ( option. state &  QStyle:: State_Selected) 
            painter-> fillRect ( option. rect,  option. palette. highlight ( ) ) ; 
        QImage image =  qvariant_cast < QImage> ( index. data ( Qt:: DecorationRole) ) ; 
        
        QRect rect =  option. rect; 
        int  x =  rect. x ( )  +  10 ; 
        int  y =  rect. y ( )  +  5 ; 
        QBrush brush; 
        
        brush. setTexture ( m_gridPixmap) ; 
        painter-> fillRect ( x,  y,  40 ,  40 ,  brush) ; 
        
        painter-> drawImage ( x,  y,  image) ; 
        QRect textRect ( rect. x ( )  +  60 ,  rect. y ( ) ,  rect. width ( )  -  60 ,  rect. height ( ) ) ; 
        QString layerName =  index. model ( ) -> data ( index,  Qt:: DisplayRole) . toString ( ) ; 
        QTextOption textOption =  Qt:: AlignLeft |  Qt:: AlignVCenter; 
        painter-> drawText ( textRect,  layerName,  textOption) ; 
    } 
    else 
    { 
        QStyledItemDelegate :: paint ( painter,  option,  index) ; 
    } 
} 
bool  LayerItemDelegate :: editorEvent ( QEvent *  event, 
    QAbstractItemModel *  model, 
    const  QStyleOptionViewItem &  option, 
    const  QModelIndex &  index) 
{ 
    return  false ; 
} 
QWidget * LayerItemDelegate :: createEditor ( QWidget * parent, 
    const  QStyleOptionViewItem & option, 
    const  QModelIndex & index)  const 
{ 
    qDebug ( )  <<  "createEditor" ; 
    if  ( index. column ( )  ==  1 )  
    { 
        QLineEdit*  edit =  new  QLineEdit ( parent) ; 
        edit-> setFixedHeight ( 33 ) ; 
        edit-> setContentsMargins ( 48 ,  15 ,  50 ,  0 ) ; 
        return  edit; 
    } 
    else  return  0 ;   
} 
void  LayerItemDelegate :: setEditorData ( QWidget * editor,  const  QModelIndex & index)  const 
{ 
    QString value =  index. model ( ) -> data ( index,  Qt:: EditRole) . toString ( ) ; 
    QLineEdit * edit =  static_cast < QLineEdit* > ( editor) ; 
    edit-> setText ( value) ; 
    qDebug ( )  <<  "setEditorData" ; 
} 
void  LayerItemDelegate :: updateEditorGeometry ( QWidget * editor, 
    const  QStyleOptionViewItem & option,  const  QModelIndex &  index )  const 
{ 
    editor-> setGeometry ( option. rect) ; 
} 
void  LayerItemDelegate :: setModelData ( QWidget * editor,  QAbstractItemModel * model, 
    const  QModelIndex & index)  const 
{ 
    qDebug ( )  <<  "setModelData" ; 
    QLineEdit * edit =  static_cast < QLineEdit* > ( editor) ; 
    model-> setData ( index,  edit-> text ( ) ,  Qt:: EditRole) ; 
} 
  
 layertablemodel.h  
# ifndef  LAYERLISTMODEL_H  
# define  LAYERLISTMODEL_H  
# include  <QAbstractTableModel>  
# include  <QStringList>  
# include  <QList>  
# include  <QPixmap>  
# include  <QImage>  
# include  <QIcon>  
# include  <QDebug>  
# include  <QItemSelectionModel>  
class  LayerTableModel  :  public  QAbstractTableModel  
{ 
    Q_OBJECT
public : 
    LayerTableModel ( QObject * parent =  0 ) ; 
    ~ LayerTableModel ( ) ; 
    int  rowCount ( const  QModelIndex & parent)  const ; 
    int  columnCount ( const  QModelIndex & parent)  const ; 
    QVariant data ( const  QModelIndex & index,  int  role)  const ; 
    QVariant headerData ( int  section, 
        Qt:: Orientation orientation, 
        int  role =  Qt:: DisplayRole)  const ; 
    Qt:: ItemFlags flags ( const  QModelIndex & index)  const ; 
    bool  setData ( const  QModelIndex & index,  const  QVariant & value,  int  role) ; 
    void  deleteItem ( int  index) ; 
    void  addItem ( const  QString & layerName, const  QImage & thumbnail,  bool  isShow =  true ) ; 
    void  refreshModel ( ) ; 
    QModelIndex selecttedIndex ( int  row) ; 
    void  setSelecttedRow ( int  row) ; 
    int  getSelecttedRow ( )  const ; 
public  slots: 
    void  changeLayerVisibility ( const  QModelIndex& ) ; 
private : 
    struct  LayerItem 
    { 
        QString layerName; 
        QImage thumbnail; 
        float  transparence; 
        bool  isShow; 
    } ; 
    QList< LayerItem>  layerList; 
    int  selectedRow; 
} ; 
# endif   
  
 layertablemodel.cpp  
# include  "layertablemodel.h"  
# include "QString"  
LayerTableModel :: LayerTableModel ( QObject * parent) 
:  QAbstractTableModel ( parent) 
{ 
    QImage image ( "images\\sample.jpg" ) ; 
    layerList. reserve ( 3 ) ; 
    selectedRow =  0 ; 
    for  ( int  i =  0 ;  i <  1 ;  i++ ) 
    { 
        addItem ( QString ( ) , image, true ) ; 
    } 
} 
LayerTableModel :: ~ LayerTableModel ( ) 
{ 
} 
QVariant LayerTableModel :: data ( const  QModelIndex & index,  int  role)  const 
{ 
    if  ( ! index. isValid ( ) ) 
        return  QVariant ( ) ; 
    int  column =  index. column ( ) ; 
    if  ( column ==  0 ) 
    { 
        if ( role ==   Qt:: CheckStateRole) 
        { 
            return  layerList. at ( index. row ( ) ) . isShow ?  Qt:: Checked :  Qt:: Unchecked; 
        } 
        if  ( role ==  Qt:: SizeHintRole) 
        { 
            return  QSize ( 20 ,  50 ) ; 
        } 
    } 
    else 
    { 
        if  ( role ==  Qt:: EditRole) 
        { 
            return  QVariant ( layerList. at ( index. row ( ) ) . layerName) ; 
        } 
        if  ( role ==  Qt:: DisplayRole) 
        { 
            return  QVariant ( layerList. at ( index. row ( ) ) . layerName) ; 
        } 
        if  ( role ==  Qt:: DecorationRole) 
        { 
            if  ( layerList. at ( index. row ( ) ) . thumbnail. isNull ( ) ) 
            { 
                return   layerList. at ( index. row ( ) ) . thumbnail; 
            } else 
            { 
                return   layerList. at ( index. row ( ) ) . thumbnail. scaledToHeight ( 40 ) ; 
            } 
        } 
        if  ( role ==  Qt:: SizeHintRole) 
        { 
            return  QSize ( 200 ,  50 ) ; 
        } 
        if  ( role ==  Qt:: TextAlignmentRole) 
        { 
            return  int ( Qt:: AlignVCenter) ; 
        } 
    } 
    return  QVariant ( ) ; 
} 
int  LayerTableModel :: rowCount ( const  QModelIndex & parent)  const 
{ 
    return  ( parent. isValid ( )  &&  parent. column ( )  !=  0 )  ?  0  :  layerList. size ( ) ; 
} 
int  LayerTableModel :: columnCount ( const  QModelIndex & parent)  const 
{ 
    Q_UNUSED ( parent) ; 
    return  2 ; 
} 
QVariant LayerTableModel :: headerData ( int  section,  Qt:: Orientation orientation,  int  role)  const 
{ 
    if  ( role ==  Qt:: DisplayRole) 
        return  QString :: number ( section) ; 
    
        
    return  QAbstractItemModel :: headerData ( section,  orientation,  role) ; 
} 
Qt:: ItemFlags LayerTableModel :: flags ( const  QModelIndex & index)  const 
{ 
    if  ( ! index. isValid ( ) ) 
        return  0 ; 
    if  ( index. column ( )  ==  0 ) 
        return  Qt:: ItemIsEnabled |  Qt:: ItemIsUserCheckable; 
    return   Qt:: ItemIsEnabled |  Qt:: ItemIsSelectable |  Qt:: ItemIsEditable; 
} 
bool  LayerTableModel :: setData ( const  QModelIndex & index,  const 
    QVariant & value,  int  role) 
{ 
    if  ( ! index. isValid ( ) ) 
    { 
        return  false ; 
    } 
    if  ( role ==  Qt:: CheckStateRole &&  value. type ( )  ==  QVariant:: Bool) 
    { 
        layerList[ index. row ( ) ] . isShow =  value. toBool ( ) ; 
        emit ( dataChanged ( index,  index) ) ; 
        return  true ; 
    } 
    if  ( role ==  Qt:: EditRole &&  index. column ( )  ==  1 ) 
    { 
        layerList[ index. row ( ) ] . layerName =  value. toString ( ) ; 
        emit ( dataChanged ( index,  index) ) ; 
        return  true ; 
    } 
    return  false ; ; 
} 
void  LayerTableModel :: changeLayerVisibility ( const  QModelIndex&  index) 
{ 
    if  ( index. isValid ( ) && index. column ( )  ==  0 ) 
    { 
        setData ( index,  ! ( layerList. at ( index. row ( ) ) . isShow) ,  Qt:: CheckStateRole) ; 
    } 
} 
void  LayerTableModel :: deleteItem ( int  index) 
{ 
    QList< LayerItem> :: iterator it =  layerList. begin ( ) ; 
    layerList. erase ( it +  index) ; 
} 
void  LayerTableModel :: addItem ( const  QString & name, const  QImage & thumb,  bool  show) 
{ 
    LayerItem item; 
    if  ( name. size ( )  ==  0 ) 
    { 
        item. layerName =  QString ( "Layer " )  +  QString :: number ( layerList. size ( ) ) ; 
    } else { 
        item. layerName =  name; 
    } 
    item. isShow =  show; 
    item. thumbnail =  thumb; 
    layerList. append ( item) ; 
    
    
    qDebug ( ) << layerList. size ( ) ; 
} 
void  LayerTableModel :: refreshModel ( ) 
{ 
    beginResetModel ( ) ; 
    endResetModel ( ) ; 
    
} 
QModelIndex LayerTableModel :: selecttedIndex ( int  row) 
{ 
    return  this -> createIndex ( row,  1 ) ; 
} 
void  LayerTableModel :: setSelecttedRow ( int  row) 
{ 
    selectedRow =  row; 
} 
int  LayerTableModel :: getSelecttedRow ( )  const 
{ 
    return  selectedRow; 
} 
  
 layertableview.h  
# ifndef  LAYERLISTVIEW_H  
# define  LAYERLISTVIEW_H  
# include  <QTableView>  
# include  <QMouseEvent>  
# include  <QDebug>  
# include  <QHeaderView>  
# include  <QStandardItemModel>  
# include  <QContextMenuEvent>  
# include  <QMenu>  
# include  "layertablemodel.h"  
# include  "layeritemdelegate.h"  
class  LayerTableView  :  public  QTableView  
{ 
    Q_OBJECT
public : 
    LayerTableView ( QWidget * parent =  0 ) ; 
    ~ LayerTableView ( ) ; 
    void  setLayerSize ( QSize s) ; 
public  slots: 
    void  addNewLayer ( ) ; 
    void  deleteLayer ( ) ; 
protected : 
    void  mouseMoveEvent ( QMouseEvent *  event) ; 
    void  contextMenuEvent ( QContextMenuEvent *  event) ; 
private : 
    LayerItemDelegate * delegate; 
    LayerTableModel * model; 
    QSize layerSize; 
private  slots: 
    void  itemClicked ( const  QModelIndex& ) ; 
} ; 
# endif   
  
 layertableview.cpp  
# include  "layertableview.h"  
# include  <QMessageBox>  
LayerTableView :: LayerTableView ( QWidget * parent) 
    :  QTableView ( parent) 
{ 
    delegate =  new  LayerItemDelegate ( ) ; 
    model =  new  LayerTableModel ( ) ; 
    this -> setContentsMargins ( 0 ,  0 ,  0 ,  0 ) ; 
    this -> setModel ( model) ; 
    this -> setItemDelegate ( delegate) ; 
    this -> horizontalHeader ( ) -> setStretchLastSection ( true ) ; 
    this -> horizontalHeader ( ) -> setHighlightSections ( false ) ; 
    this -> setFrameShape ( QFrame:: NoFrame) ; 
    this -> setColumnWidth ( 0 ,  30 ) ; 
    this -> setColumnWidth ( 1 ,  170 ) ; 
    this -> verticalHeader ( ) -> setVisible ( false ) ; 
    this -> horizontalHeader ( ) -> setVisible ( false ) ; 
    this -> resizeColumnsToContents ( ) ; 
    this -> resizeRowsToContents ( ) ; 
    
    this -> setMouseTracking ( true ) ; 
    
    connect ( this ,  SIGNAL ( clicked ( const  QModelIndex& ) ) ,  this ,  SLOT ( itemClicked ( const  QModelIndex& ) ) ) ; 
} 
LayerTableView :: ~ LayerTableView ( ) 
{ 
} 
void  LayerTableView :: mouseMoveEvent ( QMouseEvent *  event) 
{ 
    Q_UNUSED ( event) ; 
} 
void  LayerTableView :: contextMenuEvent ( QContextMenuEvent *  event) 
{ 
    QMenu * pMenu =  new  QMenu ( this ) ; 
    QAction * pAddGroupAct =  new  QAction ( tr ( "Delete" ) ,  pMenu) ; 
    pMenu-> addAction ( pAddGroupAct) ; 
    pMenu-> popup ( mapToGlobal ( event-> pos ( ) ) ) ; 
} 
void  LayerTableView :: addNewLayer ( ) 
{ 
    model-> addItem ( QString ( ) ,  QImage ( layerSize,  QImage:: Format_RGB32) ,  true ) ; 
    
    model-> refreshModel ( ) ; 
    this -> resizeRowsToContents ( ) ; 
} 
void  LayerTableView :: itemClicked ( const  QModelIndex&  index) 
{ 
    if  ( index. isValid ( )  ) 
    { 
        
        if  ( index. column ( )  ==  0 ) 
        { 
            
            model-> changeLayerVisibility ( index) ; 
            QModelIndex tmp =  model-> selecttedIndex ( model-> getSelecttedRow ( ) ) ; 
            this -> selectionModel ( ) -> select ( tmp,  QItemSelectionModel:: Select) ; 
        } 
        
        else  if  ( index. column ( )  ==  1 ) 
        { 
            model-> setSelecttedRow ( index. row ( ) ) ; 
        } 
    } 
} 
void  LayerTableView :: deleteLayer ( ) 
{ 
    model-> deleteItem ( model-> getSelecttedRow ( ) ) ; 
    model-> refreshModel ( ) ; 
    QModelIndex tmp =  model-> selecttedIndex ( 0 ) ; 
    this -> selectionModel ( ) -> select ( tmp,  QItemSelectionModel:: Select) ; 
} 
void  LayerTableView :: setLayerSize ( QSize s) 
{ 
    layerSize =  s; 
} 
  
 mainwindow.h  
# ifndef  MAINWINDOW_H  
# define  MAINWINDOW_H  
# include  <QMainWindow>  
# include "layertableview.h"  
QT_BEGIN_NAMESPACE
namespace  Ui {  class  MainWindow ;  } 
QT_END_NAMESPACE
class  MainWindow  :  public  QMainWindow  
{ 
    Q_OBJECT
public : 
    MainWindow ( QWidget * parent =  nullptr ) ; 
    ~ MainWindow ( ) ; 
private : 
    Ui:: MainWindow * ui; 
    LayerTableView * myLayerTableView; 
} ; 
# endif   
  
 mainwindow.cpp  
# include  "mainwindow.h"  
# include  "ui_mainwindow.h"  
# include "QHBoxLayout"  
MainWindow :: MainWindow ( QWidget * parent) 
    :  QMainWindow ( parent) 
    ,  ui ( new  Ui:: MainWindow) 
{ 
    ui-> setupUi ( this ) ; 
    
    myLayerTableView =  new  LayerTableView ( ) ; 
    
    QHBoxLayout * layout =  new  QHBoxLayout; 
    
    layout-> addWidget ( myLayerTableView) ; 
    
    QWidget * centralWidget =  new  QWidget; 
    centralWidget-> setLayout ( layout) ; 
    
    setCentralWidget ( centralWidget) ; 
} 
MainWindow :: ~ MainWindow ( ) 
{ 
    delete  ui; 
}