如何在Qt中将选定的行向上移动

3
我有一个包含3行2列的QTableView(在这里我使用了QStandardItemModel)。我想在QPushButton被点击时上移/下移单个行。如何在QTableView中上移/下移行?感谢你的回复vahancho。我已经尝试使用QAbstractItemModel :: moveRow,但它无效:
   int currentRow = ui->tableView->currentIndex().row();
   QModelIndex sourceParent = ui->tableView->model()->index(ui->tableView->selectionModel()->currentIndex().row(),0);
   QModelIndex destinationParent = ui->tableView->model()->index(ui->tableView->selectionModel()->currentIndex().row()+1,0);
   ui->tableView->model()->moveRow(sourceParent,currentRow, destinationParent,destinationParent.row());

它不起作用是因为它是一个虚函数,你必须自己实现它。 - eric
2
神经网络,谢谢您的回复。那么,您是说如果不自己实现moveRow()函数,它什么也不会做吗?那么这个函数的想法是什么? - Angie Quijano
5个回答

6

使用Qt文档了解QStandardItemModel - QStandardItemModel类

  1. takeRow:删除并返回指定行。
  2. insertRow:在指定位置插入一个新的行。

我同意,QStandardItemModel 更加方便 :) - Zaiborg
我向作者发布了解决方案,但他删除了我的帖子。问题在于 TypeScript 不知道类型转换,因此他无法将 QModelIndex::model() 强制转换为 QStandardItemModel。 - Dmitry Sazonov
@SaZ 是谁?TS 是什么意思?他删除了帖子,他的声望这么低他能这样做吗? - eric
TS是主题发起人。他发布了一个答案,我对其进行了评论。所以他删除了他的答案,我的评论也变得不可见了。 - Dmitry Sazonov

3

这是一个我用来移动QAbstractItemModel中一行的Qt :: DisplayData的简短实用程序:

void CopyRowData( QAbstractItemModel * pModelDst, const QAbstractItemModel * pModelSrc, int nRowDst, int nRowSrc, const QModelIndex &parentDst /*= QModelIndex()*/, const QModelIndex &parentSrc /*= QModelIndex()*/, int nRole /*= Qt::DisplayRole*/ )
{
    if (parentSrc.isValid())
        assert(parentSrc.model() == pModelSrc);
    if (parentDst.isValid())
        assert(parentDst.model() == pModelDst);

    int nCols = pModelSrc->columnCount(parentSrc);

    for (int i = 0; i < nCols ; ++i)
        pModelDst->setData(pModelDst->index(nRowDst, i, parentDst), pModelSrc->index(nRowSrc, i, parentSrc).data(nRole), nRole);
}

bool MoveModelRows( QAbstractItemModel * pModel, int nSrcRow, int nDstRow, int nCount /*= 1*/, const QModelIndex &parent /*= QModelIndex()*/ )
{
    if (nSrcRow < 0 || nSrcRow >= pModel->rowCount(parent) ||
        nDstRow < 0 || nDstRow >= pModel->rowCount(parent))
        return false;

    if (nSrcRow == nDstRow)
        return true;

    int nDstRowNew = nSrcRow > nDstRow ? nDstRow : nDstRow + 1;

    if (!pModel->insertRows(nDstRowNew, nCount, parent))
        return false;

    int nSrcRowNew = nSrcRow > nDstRow ? nSrcRow + nCount : nSrcRow;

    for (int i = 0; i < nCount; ++i)
        CopyRowData(pModel, pModel, nDstRowNew + i, nSrcRowNew + i, parent, parent);

    pModel->removeRows(nSrcRowNew, nCount, parent);

    return true;
}

3
如果您使用Qt5,可以查看此功能:

bool QAbstractItemModel::moveRow(const QModelIndex & sourceParent, int sourceColumn, const QModelIndex & destinationParent, int destinationChild)

在支持此操作的模型上,将sourceColumn从sourceParent移动到destinationParent下的destinationChild。如果成功移动列,则返回true;否则返回false。


2
抽象项模型,这意味着你仍然需要自己实现它,对吧? - eric
@neuronet,是的。实际上,要使moveRow()起作用,您需要实现QAbstractItemModel :: moveRows()虚函数。 - vahancho
1
很奇怪的是,虽然这个虚函数可用,但没有 Qt 类实现它。 - Rotsiser Mho

0

使用SaZ提出的想法:

使用Qt文档中的QStandardItemModel - QStandardItemModel Class

  1. takeRow
  2. insertRow

这是我为此目的编写的代码:

QModelIndexList selection = ui->tableView->selectionModel()->selectedRows();
int row = selection[0].row();
QList<QStandardItem*> itemList = ui->tableView->model()->takeRow(row);
ui->tableView->model()->insertRow(row-1,itemList);

希望这能帮到你。


-1

我认为这会有所帮助:

for(int colId=0;colId<ui->tableWidget->columnCount();++colId)
{
    QTableWidgetItem *item1=new QTableWidgetItem( *ui->tableWidget->item(id_row1,colId) );
    QTableWidgetItem *item2=new QTableWidgetItem( *ui->tableWidget->item(id_row2,colId) );

    ui->tableWidget->setItem(id_row1,colId, item2 );
    ui->tableWidget->setItem(id_row2,colId, item1 );
}

这会创建不必要的副本,使用相对昂贵的堆分配。 - Rotsiser Mho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接