pyqt5 tableView实现excel拖曳填充

和tableWidget实现excel拖曳填充大同小异,见代码中MyTableView类,其他类只用于演示,无大作用。

python 复制代码
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import QPoint, Qt, QCoreApplication, pyqtSlot
from PyQt5.QtGui import  QBrush, QPixmap, QColor, QPainter,QIcon,QPolygon
from PyQt5 import QtWidgets,QtCore
from PyQt5.QtCore import pyqtSignal
import logging
class MyTableView(QtWidgets.QTableView):
    dragbottom = pyqtSignal(object)
    def __init__(self,parent):
        super().__init__(parent)
        self.cellBottomRight=False
        self.leftbuttonDown=False
    def show_select(self):
        painter=QPainter(self.viewport())
        pen = painter.pen();
        pen.setWidth(1);
        selections = self.selectionModel()
        if selections!=None:
            # logging.info("not None")
            list1 = selections.selectedIndexes()
            for i in range(len(list1)):
                modelIndex = list1[i]
                #QRect类提供各种矩形坐标,绘制线跟点的时候需要用到坐标
                rect = self.visualRect(modelIndex);
                tmpRect=QtCore.QRect(QtCore.QPoint(rect.x()+1,rect.y()+1),QtCore.QSize(rect.width()-2,rect.height()-2))
                #如果是选中状态 并且在选择公式状态
                #给选中单元格进行画线画点
                dashes=[]
                penXu = painter.pen();
                #设置画笔宽度
                penXu.setWidth(2);
                color=QColor();
                #设置画笔颜色
                color.setRgb(31,187,125);
                penXu.setColor(color);
                painter.setPen(penXu);
                #绘制单元格四周的线
                # print(dir(tmpRect))
                painter.drawRect(tmpRect);
                #绘制单元格右下角点
                penXu.setWidth(6);
                painter.setPen(penXu);
                painter.drawPoint(tmpRect.x()+tmpRect.width() -3,tmpRect.y()+tmpRect.height()-3);

    def paintEvent(self,e):
        super().paintEvent(e)
        self.show_select()
    #鼠标移动事件
    def mouseMoveEvent(self,event):
        #获取鼠标位置信息
        # logging.info(event)
        if not self.cellBottomRight:
            # logging.info("not bottom")
            mousePos =event.pos();
            #获取所有选中单元格
            # logging.info(self.cellBottomRight)
            selections = self.selectionModel()
            if selections==None:
                return;
            list1 = selections.selectedIndexes()
            if len(list1)>0:
                modelIndex = list1[-1]
                #获取最后一个选中的单元格的QRect,用来判断是否鼠标位置是否在右下角区域
                rect = self.visualRect(modelIndex);
                # logging.info([mousePos,rect])
                #判断是否在我们规定的区域,或者是按下模式,isClick是按下模式标志
                # print(dir(mousePos))
                if((mousePos.x() >= (rect.x()+rect.width() -7) and mousePos.x() <= (rect.x()+rect.width())
                    and mousePos.y() >= (rect.y()+rect.height()-7) and mousePos.y() <= (rect.y()+rect.height()))):
                    logging.info("right bottom")
                    #设置鼠标在右下角区域样式
                    self.setCursor(Qt.CrossCursor);
                    #在右下角区域
                    self.cellBottomRight = True;
        super().mouseMoveEvent(event);
        #鼠标点击事件
    def mousePressEvent(self,event):
        if(event.button()==Qt.LeftButton):
            self.leftbuttonDown = True;
            self.setCursor(Qt.SizeAllCursor);
        else:
            self.leftbuttonDown = False;
            self.setCursor(Qt.ArrowCursor);
        super().mousePressEvent(event);#提交鼠标给控件
    def mouseReleaseEvent(self,ev):
        if self.leftbuttonDown and self.cellBottomRight:
            selections = self.selectionModel()
            if selections!=None:
                list1 = selections.selectedIndexes()
                if len(list1)>0:
                    logging.info("dragbottom")
                    self.dragbottom.emit(list1)
        self.leftbuttonDown = False;
        self.cellBottomRight = False;
        self.setCursor(Qt.ArrowCursor);
        super().mouseReleaseEvent(ev)
class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data

    def rowCount(self, parent=None):
        return len(self._data)

    def columnCount(self, parent=None):
        return len(self._data[0])

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            return str(self._data[index.row()][index.column()])

        return None

    def flags(self, index):
        return QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled | super().flags(index)

    def moveRow(self, fromIndex, toIndex):
        row = self._data.pop(fromIndex)
        self.beginInsertRows(QtCore.QModelIndex(), toIndex, toIndex)
        self._data.insert(toIndex, row)
        self.endInsertRows()

    def mimeTypes(self):
        return [QtCore.Qt.MimeType]

    def mimeData(self, indexes):
        mimedata = QtCore.QMimeData()
        encodedData = QtCore.QByteArray()

        stream = QtCore.QDataStream(encodedData, QtCore.QIODevice.WriteOnly)

        for index in indexes:
            if index.isValid():
                text = self._data[index.row()][index.column()]
                stream.writeString(text.encode("utf-8"))

        mimedata.setData("QtCore.Qt.MimeType", encodedData)
        return mimedata

    def dropMimeData(self, data, action, row, column, parent):
        if action == QtCore.Qt.IgnoreAction:
            return True

        if not data.hasFormat(QtCore.Qt.MimeType):
            return False

        if column > 0:
            return False

        if row != -1:
            self.moveRow(data.text(), row)
        else:
            self.moveRow(data.text())

        return True
def dragbottom(items):
    print(items)  
    global data
    first=items[0]
    col=first.column()
    row=first.row()
    first_value=data[row][col]
    print(dir(first))
    for one in items[1:]:
        col=one.column()
        row=one.row()
        data[row][col]=first_value
        # self.table.setItem(one.row(),one.column(),QTableWidgetItem(v))
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    data = [
        ["1", "John"],
        ["2", "Alice"],
        ["3", "Bob"]
    ]

    model = TableModel(data)

    view = MyTableView(None)
    view.dragbottom.connect(dragbottom)
    view.setModel(model)
    view.setWindowTitle("Drag and Drop")
    view.show()

    sys.exit(app.exec_())
相关推荐
2601_967980119 分钟前
Python中flatten( )函数及函数用法详解
python·numpy·数组操作·flatten函数·列表处理
xbzb13 分钟前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo
敲上瘾3 小时前
Qt Widgets入门:项目模板解析与Hello World
开发语言·数据库·c++·qt·ui·qt6.3
合尘猫3 小时前
图片表格变结构化数据:OCR 后的三个坑
python·ocr
小小张说故事4 小时前
Python 里弱引用到底弱在哪:拆开 weakref.ref、回调陷阱和 WeakValueDictionary
python
用户019027581614 小时前
用 DuckDB 存查 A 股 K 线:零服务、SQL 直接分析
python
程序员果子5 小时前
本体构建方法
人工智能·python·知识图谱·agent框架·本体
天天被压力6 小时前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
总裁余(余登武)6 小时前
【python项目】:1操作EXCEl自动化开发
python·自动化·excel
芝梵家电数据笔记6 小时前
用字段表核对暖菜板长期使用条件:结构、暖区、质保边界
python·家电·数据校验·dataclass·选购