一个表格的进化史(五)

2018-04-18 22:59:45  阅读 76 次 评论 0 条

  上一篇我们使用setCellWidget来帮助我们在表格中进行编辑操作,当有很多行都需要同样的操作时这种方法就感觉有点繁琐了。特别是当需要使用信号/槽时。不过幸运的是Qt给我们提供了更高大上的办法:delegate(委托,也有翻译为代理的)。那么我们该如何操作呢?

   1.首先从Item代理类中派生一个自己的类。如:

class MyTableItemDelegate : public QStyledItemDelegate

   然后重写createEditor函数:

 if(index.column() == 3)
    {
       QComboBox* cbx = new QComboBox(parent);
       cbx->addItem(QStringLiteral("男"));
       cbx->addItem(QStringLiteral("女"));
       return cbx;
    }else{
        return QStyledItemDelegate::createEditor(parent,option,index);
    }

   判断当前如果是第4列(下标为3)时,创建一个下拉框并添加两个Item然后返回,其他列使用默认方法处理。最后让表格使用这个代理:

ui->tableWidget->setItemDelegate(new MyTableItemDelegate);

blob.png

我们看到了和使用setCellWidget一样的效果,只不过用这样的方式更简洁一点。我们不仅可以给表格设置代理,还可以为指定行或列设置代理。

void  setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)  //为列设置代理
void  setItemDelegateForRow(int row, QAbstractItemDelegate *delegate  //为行设置代理

如果上面使用ui->tableWidget->setItemDelegateForColumn(3,new MyTableItemDelegate)。那么在createEditor函数中就不需要判断当前列了。


故事到这里还没有结束,如果我们使用图片替换下拉框中的文字时就会发现一个问题:

    if(index.column() == 3)
    {
       QComboBox* cbx = new QComboBox(parent);
       cbx->addItem(QIcon("f:/05_test/tx.jpg"),"");  //只显示图片
       cbx->addItem(QIcon("f:/05_test/tx2.jpg"),"");
       return cbx;
    }else{
        return QStyledItemDelegate::createEditor(parent,option,index);
    }

blob.png

通过下拉框选择后表格中的内容为空。其实同时还存在另一个问题,那就是当设置了表格中的内容后下拉框中的内容不会跟着改。换句话说就是单元格和创建的编辑器内容不同步。

  当遇到这样的情况时,我们还需要重写两个函数,手动将两边的数据对应起来即:

//virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;//设置模型的数据
//virtual void setEditorData(QWidget *editor, const QModelIndex &index) const; //设置编辑器的数据


void MyTableItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if(index.column() == 3){
        QComboBox* cbx = qobject_cast<QComboBox*>(editor);
        if(cbx->currentIndex() == 0){
            model->setData(index,QStringLiteral("男"));
        }else{
            model->setData(index,QStringLiteral("女"));
        }
    }
}


void MyTableItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if(index.column() == 3){
        QComboBox* cbx = qobject_cast<QComboBox*>(editor);
        QString str = index.model()->data(index).toString();
        if(str == QStringLiteral("男")){
            cbx->setCurrentIndex(0);
        }else{
            cbx->setCurrentIndex(1);
        }
    }
}


本文地址:http://fearlazy.com/index.php/post/66.html
版权声明:本文为原创文章,版权归 fearlazy 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?