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;
}