所需待重写函数:

[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event); 
/* 
 * Filters events if this object has been installed as an event filter for the watched object. 
 * In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false. 
 */ 

以上来自官方帮助手册

说明:

  1. 通过事件过滤器,即上述重写函数,可通过条件,筛选所需事件
  2. 如果筛选成功,如果此事件后续不再使用,返回true,后续如果再次使用,返回false
  3. 如果筛选不成功,则返回给父类,防止父类处于内部目的重新实现了 eventFilter()

代码示例:

  1. MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTableWidget>

#define STANDFLDCOL		0
#define LAYERFLDCOL		1

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    bool eventFilter(QObject *watched, QEvent *event);

private:
    /* init table widget cell data */
    void InitCellData();

    /* mouse press event */
    void MousesPressEvent(QMouseEvent *event);

    /* mouse move event */
    void MousesMoveEvent();

    /* mouse release event */
    void MousesReleaseEvent(QMouseEvent *event);

    /* exchange cell data between drag cell and drop cell */
    void ExchangeData(int oldRow, int oldCol, int newRow, int newCol, QTableWidget *focusTable);

private:
    Ui::MainWindow *ui;
    int 	m_selectRow;	// drag row
    bool 	m_isPress;		// mouse press
    bool 	m_isDrag;		// mouse is drag
};

#endif // MAINWINDOW_H

说明:

void InitCellData() : 初始化表格内容
void MousesPressEvent() : 如果事件过滤器中筛选了鼠标左键按下事件,则调用该函数
void MousesMoveEvent() : 如果事件过滤器筛选了鼠标移动事件,则调用该函数
void MousesReleaseEvent() : 如果事件过滤器筛选了鼠标释放事件,则调用该函数
void ExchangeData() : 交换拖拽起始单元格和最终单元格item

  1. MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMouseEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_isPress 	= false;
    m_isDrag 	= false;

    InitCellData();
}

MainWindow::~MainWindow()
{
    ui->tableWidget->clear();
    delete ui;
}

void MainWindow::InitCellData()
{
    ui->tableWidget->viewport()->installEventFilter(this);
    ui->tableWidget->horizontalHeader()->setVisible(false);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget->setColumnCount(2);
    ui->tableWidget->setRowCount(15);

    for (int i = 0; i < 15; i++)
    {
        QTableWidgetItem *aitem = new QTableWidgetItem(QString("%1ATime").arg(i));
        aitem->setFlags(aitem->flags()&(~Qt::ItemIsEditable));
        ui->tableWidget->setItem(i, STANDFLDCOL, aitem);

        QTableWidgetItem *bitem = new QTableWidgetItem(QString("%1BTime").arg(i));
        bitem->setFlags(bitem->flags()&(~Qt::ItemIsEditable));
        ui->tableWidget->setItem(i, LAYERFLDCOL, bitem);
    }
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->tableWidget->viewport())
    {
        QMouseEvent *pEvent = static_cast<QMouseEvent*>(event);
        if (event->type() == QEvent::MouseButtonPress)
        {
            MousesPressEvent(pEvent);
            return true;
        }
        else if (event->type() == QEvent::MouseMove)
        {
            MousesMoveEvent();
            return true;
        }
        else if (event->type() == QEvent::MouseButtonRelease)
        {
            MousesReleaseEvent(pEvent);
            return true;
        }
        else return false;
    }
    return QMainWindow::eventFilter(watched, event);
}

void MainWindow::MousesPressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (STANDFLDCOL == ui->tableWidget->columnAt(event->x()))
        {
            return;
        }
        m_isPress 	= true;
        m_isDrag 	= false;
        m_selectRow = ui->tableWidget->rowAt(event->y());
        ui->tableWidget->clearFocus();
    }
}

void MainWindow::MousesMoveEvent()
{
    if (m_isPress && !m_isDrag)
    {
        m_isDrag 	= true;
    }
}

void MainWindow::MousesReleaseEvent(QMouseEvent *event)
{
    if (m_isPress && m_isDrag)
    {
        m_isPress 	= false;
        m_isDrag 	= false;

        if (STANDFLDCOL == ui->tableWidget->columnAt(event->x()))
        {
            return;
        }
        ExchangeData(m_selectRow, LAYERFLDCOL, ui->tableWidget->rowAt(event->y()), LAYERFLDCOL, ui->tableWidget);
    }
}

void MainWindow::ExchangeData(int oldRow, int oldCol, int newRow, int newCol, QTableWidget *focusTable)
{
    QTableWidgetItem *oldItem = focusTable->takeItem(oldRow, oldCol);
    QTableWidgetItem *newItem = focusTable->takeItem(newRow, newCol);
    focusTable->setItem(oldRow, oldCol, newItem);
    focusTable->setItem(newRow, newCol, oldItem);
}

说明:

限制拖拽列只能为第2列(可进行修改)
限值不同列之间不能进行拖拽(可进行修改)

版权声明:本文为lsm-3-7原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/lsm-3-7/p/14357847.html