代码主要涉及鼠标事件和绘图,selectionModel,selectedIndexes。
import sys
from PyQt5.QtCore import QPoint, Qt, QCoreApplication, pyqtSlot
from PyQt5.QtGui import QBrush, QPixmap, QColor, QPainter,QIcon,QPolygon
from PyQt5.QtWidgets import (QAction, QColorDialog, QComboBox, QDialog, QFontDialog,QGroupBox, QHBoxLayout, QMainWindow, QLabel,QLineEdit, QMessageBox, QPushButton, QToolBar,QTableWidgetItem, QTableWidget, QVBoxLayout, QWidget)
from PyQt5.QtCore import pyqtSignal
from PyQt5 import QtWidgets
import logging
class MyTableWidget(QTableWidget):dragbottom = pyqtSignal(object)def __init__(self,parent):super().__init__(parent)self.cellBottomRight=Falseself.leftbuttonDown=Falsedef paintEvent(self,e):super().paintEvent(e)painter=QPainter(self.viewport())# painter.save();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))#如果是选中状态 并且在选择公式状态# if (self.item(i,j).isSelected()):#给选中单元格进行画线画点dashes=[]penXu = painter.pen();#设置画笔宽度penXu.setWidth(2);color=QColor();#设置画笔颜色color.setRgb(31,187,125);penXu.setColor(color);painter.setPen(penXu);#绘制单元格四周的线painter.drawRect(tmpRect);#绘制单元格右下角点penXu.setWidth(6);painter.setPen(penXu);painter.drawPoint(tmpRect.x()+tmpRect.width() -3,tmpRect.y()+tmpRect.height()-3);#恢复QPainter对象# painter.restore();# self.viewport().update();#鼠标移动事件def mouseMoveEvent(self,event):#获取鼠标位置信息if not self.cellBottomRight:mousePos =event.pos();#获取所有选中单元格# logging.info(self.cellBottomRight)itemList = self.selectedItems();#没有选中单元格 就退出if len(itemList) <= 0:return;modelIndex = self.indexFromItem(itemList[len(itemList)-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:itemList = self.selectedItems();if len(itemList)>0:logging.info("dragbottom")self.dragbottom.emit(itemList)self.leftbuttonDown = False;self.cellBottomRight = False;self.setCursor(Qt.ArrowCursor);super().mouseReleaseEvent(ev)
class Table(QWidget):def __init__(self):super().__init__()self.setGeometry(300, 300, 500, 400)self.setWindowTitle('QTableWidget的基本用法')layout = QHBoxLayout()self.table = MyTableWidget(None)self.table.dragbottom.connect(self.dragbottom_trig)m=4n=3self.table.setRowCount(4)self.table.setColumnCount(3)layout.addWidget(self.table)self.table.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])for i in range(m):for j in range(n):item1 = QTableWidgetItem('')self.table.setItem(i,j,item1)item1 = QTableWidgetItem('张三')self.table.setItem(0,0,item1)item2 = QTableWidgetItem('男')self.table.setItem(0, 1, item2)item3 = QTableWidgetItem('50')self.table.setItem(0, 2, item3)self.setLayout(layout)def dragbottom_trig(self,items):print(items) first=items[0]col=first.column()row=first.row()print(dir(first))v=first.text()for one in items[1:]:self.table.setItem(one.row(),one.column(),QTableWidgetItem(v))
if __name__ == "__main__":app = QApplication(sys.argv)form = Table()form.show()sys.exit(app.exec_())