主要通过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);
}