QTableView中使用组合框的两种方法

时间:2024-03-27 08:46:37

方法一:使用自定义数据模型继承QAbstractTableModel

        重载函数rowCount、columnCount、headerData、data、flags和setdata显示和编辑item对象。对enum Qt::ItemDataRole中角色的使用,可以控制一个item显示一个或者多个控件。常用的是DisplayRole和EditRole,有此两个角色可以把item当作编辑框使用。DecorateRole可以在项中添加图标,BackGroudRole和ForeGroudRole可以给背景色和字体上色,CheckStateRole可以给项添加一个QCheckBox控件。UserRole为自定义角色,当角色比较复杂时需要拓展角色,在UserRole+0/1…以上开始拓展。以上角色都是可以组合共存。可以实现如下表格效果:

QTableView中使用组合框的两种方法

上述方法有一个缺陷,item中只能使用提供的这几个默认控件,自定义控件或者其他的组合控件就没办法加载进item中,除非使用自定义代理。下面介绍自定义代理可以解决这个问题。

方法二:使用自定义代理继承QItemDelegate

        重载paint、createEditor、setEditorData、setModelData、sizeHint、updateEditorGeometry、editorEvent。

        Paint中绘制显示的组合控件的方法如下,如果不重写此paint,则显示的自定义控件都为空,只有点击时才会使用createEditor显示自定义控件:

//直接绘制

CIpCheckWidget *wdg = new CIpCheckWidget(NULL);

QPixmap pixmap(QSize(option.rect.width(), option.rect.height()));

wdg->render(&pixmap);

painter->drawPixmap(option.rect, pixmap);

//缓冲绘制

paintWidget(painter

                 ,option.rect

                 ,QString("%1-%2-%3-%4-%5,%6")

                 .arg(seleted)

                 .arg(wdg->data().str)

                 .arg(wdg->data().state)

                 .arg(wdg->data().pingState)

                 .arg(wdg->size().width())

                 .arg(wdg->size().height())

                 ,wdg);

void CMyIPDelegate::paintWidget(QPainter* painter,const QRect& rect,const QString& catchKey,QWidget* w) const

{

    QPixmap pixmap(QSize(rect.width(), rect.height()));

     if(!QPixmapCache::find(catchKey,&pixmap))

     {

         w->render(&pixmap);

         QPixmapCache::insert(catchKey,pixmap);

     }

     painter->drawPixmap(rect,pixmap);

 }

//创建部件CreateEditor,主要返回QWidget指针,通过模型索引index设置QWidget部件数据

//SetEditorData通过index模型索引设置部件数据,可以在不调用CreateEditor时,刷新item数据

//SetModelData通过部件editor设置模型model索引index的数据

其中自定义部件的数据可能不是传统数据类型,复杂数据类型自定义结构需要注册后才能作为被QVariant识别,需调用Q_DECLARE_METATYPE方法声明为元数据类型如下:

struct SMyData

{

    QString          str;

    Qt::CheckState   state;

    int              pingState;

 };

Q_DECLARE_METATYPE( SMyData)

但此方法经常会出现一个问题,每次点击编辑部件时,部件和原来图片的位置,发现会发生重叠加粗的现象,不能完全像方法一中默认委托创建出来的部件一样显示。使用updateEditorGeometry去调正效果不明显:

void CMyIPDelegate::updateEditorGeometry(QWidget *editor,

    const QStyleOptionViewItem &option, const QModelIndex & index ) const

{

    qDebug()<<"delegate::updateEditorGeometry";

    editor->setGeometry(option.rect);

    //    dynamic_cast<CIpCheckWidget*>(editor)->setFixedSize(option.rect.width(), option.rect.height());

    //  dynamic_cast<CIpCheckWidget*>(editor)->move(option.rect.topLeft());

}

勾选不同item显示如下:

QTableView中使用组合框的两种方法QTableView中使用组合框的两种方法

以上源码可参见https://github.com/ysj17366781/PortScan

除了以上QTableView,源码中还加入了获取本地网卡信息、设置本地网卡IP及ping表格中各个IP的功能。

相关文章