QTableView实现选中行上下移动操作

主要通过QStandardItemModel的两个函数takeRow和insertRow来进行操作,另外垂直表头右击菜单的自定义实现也许了解。

函数文档说明如下:


实现思路就是将指定行与它的上、下行进行内容交换,将指定的行插入到指定位置,从而实现。

为了不改变既有的代码,将实现进行封装,只需创建一个对应的对象即可,无需进行其它的任何操作。

头文件:

#ifndef QSWAPMENU_H
#define QSWAPMENU_H

#include <QObject>
#include <QStandardItemModel>
#include <QTableView>
#include <QMenu>

class QSwapMenu : public QObject
{
    Q_OBJECT
public:
    explicit QSwapMenu(QTableView *view,QWidget *parent = 0);

    void popup(const QPoint &pos,int row);

private slots:
    void onUp();
    void onDown();
    void onVerticalCustomContextMenuRequested(const QPoint &pos);

private:
    QWidget *m_pParent;//所在父窗口
    QMenu *m_pMenu;     //自定义菜单
    QTableView *m_pView;    //表
    QStandardItemModel *m_pModel;//对应的数据model
    int m_iCurRow;
};

#endif // QSWAPMENU_H
源文件:

#include "QSwapMenu.h"
#include <QAction>
#include <QHeaderView>
#include <QMessageBox>

QSwapMenu::QSwapMenu(QTableView *view, QWidget *parent) :
    QObject(parent)
{
    m_pParent = NULL;
    m_pMenu = NULL;
    m_pView = NULL;
    m_iCurRow = -1;

    m_pParent = parent;
    //有效的数据模型,表格,初始化一些需要的操作
    if(NULL == view)
        return ;
    QStandardItemModel *model = dynamic_cast<QStandardItemModel *>(view->model());
    QHeaderView *vertical = view->verticalHeader();
    if(NULL == model || NULL == vertical)
        return ;
    vertical->setContextMenuPolicy(Qt::CustomContextMenu);//自定义菜单实现
    connect(vertical,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(onVerticalCustomContextMenuRequested(QPoint)));
    m_pView = view;
    m_pModel = model;
    //初始化上移、下移菜单
    if(NULL == parent)
        return ;
    m_pMenu = new QMenu(parent);
    QAction *p1 = new QAction("up",parent);
    QAction *p2 = new QAction("down",parent);
    if(NULL == m_pMenu || NULL == p1 || NULL == p1)
        return ;
    connect(p1,SIGNAL(triggered()),this,SLOT(onUp()));
    connect(p2,SIGNAL(triggered()),this,SLOT(onDown()));
    m_pMenu->addAction(p1);
    m_pMenu->addAction(p2);
}

void QSwapMenu::onUp()
{
    int row = m_iCurRow;
    if(NULL == m_pModel || row < 0 || row > m_pModel->rowCount()-1)
    {
        QMessageBox::information(m_pParent,"tip","invalid");
        return ;
    }
    //上移需要判断是否第一行,不移动
    if(0 == row)
    {
        QMessageBox::information(m_pParent,"tip","first row");
        return ;
    }
    QList<QStandardItem *> listItem = m_pModel->takeRow(row);
    m_pModel->insertRow(row-1,listItem);
}

void QSwapMenu::onDown()
{
    int row = m_iCurRow;
    if(NULL == m_pModel || row < 0 || row > m_pModel->rowCount()-1)
    {
        QMessageBox::information(m_pParent,"tip","invalid");
        return ;
    }
    //下移需要判断最后一行,不移动
    if(row == m_pModel->rowCount()-1)
    {
        QMessageBox::information(m_pParent,"tip","last row");
        return ;
    }
    QList<QStandardItem *> listItem = m_pModel->takeRow(row);
    m_pModel->insertRow(row+1,listItem);
}

void QSwapMenu::popup(const QPoint &pos, int row)
{
    if(NULL == m_pMenu || row < 0)
        return ;
    m_pMenu->popup(pos);
    m_iCurRow = row;
}

void QSwapMenu::onVerticalCustomContextMenuRequested(const QPoint &pos)
{
    if(NULL == m_pView || NULL == m_pModel)
        return ;
    int row = m_pView->verticalHeader()->logicalIndexAt(pos);
    this->popup(QCursor::pos(),row);
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值