pyqt5 QTableWidget 表格控制元件中剪下板複製貼上的實現

Firecelyyyy發表於2020-07-09

#實現了表格控制元件中的複製貼上功能
選中區域ctrl+c複製
ctrl+v貼上,剪下板的內容會複製到被選中的單個單元格中。這一點,就算是從excel複製的資料,在QTableWidget中輸入也是一樣的情況。
再次選中單元格,按下ctrl+v,恢復格式。

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QTableWidget, QTableWidgetItem
from itertools import product
import pyperclip

class Demo(QWidget):                                         
    def __init__(self):
        self.clipboard = QApplication.clipboard()
        self.text=str()
        self.topRow=int()
        self.bottomRow=int()
        self.leftColumn=int()
        self.rightColumn=int()

        super(Demo, self).__init__()
        self.resize(650,250)        
        self.table=QTableWidget(self)
        self.table.setRowCount(6)                            
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels([('{}'.format(i))for i in range(6)])#列表解析式   # 5
        self.table.setVerticalHeaderLabels([('{}'.format(i))for i in range(6)])
        self.table.clicked.connect(self.selected)

        hbox = QHBoxLayout(self)
        hbox.addWidget(self.table)
        self.setLayout(hbox)

    def selected(self,index):#獲取選中單元格的索引
        self.index_row=index.row()
        self.index_column=index.column()

    def keyPressEvent(self, event):
        if (event.key() == Qt.Key_C) and QApplication.keyboardModifiers() == Qt.ControlModifier:
            #按鍵事件,ctrl+c時觸發,複製。
            #self.clipboard.clear()#清空剪下板,好像沒啥用
            a=self.table_copy()
            self.clipboard.setText(self.STR)
            self.STR=str()#字串歸零
        else:
            pass
        if (event.key() == Qt.Key_V) and QApplication.keyboardModifiers() == Qt.ControlModifier:
            #ctrl+v貼上
            self.table_paste()
        else:
            pass

    def table_copy(self):
        selectRect = self.table.selectedRanges()
        for r in selectRect:#獲取範圍邊界
            self.top=r.topRow()
            self.left=r.leftColumn()
            self.bottom=r.bottomRow()
            self.right=r.rightColumn()
        self.column_n=0
        self.number=0
        self.row_n=0
        self.column_n=self.right-self.left+1
        self.row_n=self.bottom-self.top+1
        self.number=self.row_n*self.column_n
        self.c=[]
        for i in range(self.number):
            self.c.append(' \t')#注意,是空格+\t
            if (i%self.column_n)==(self.column_n-1):
                self.c.append('\n')
            else:
                pass
            #這裡生成了一個列表,大小是:行X(列+1),換行符佔了一列。
            #預設情況下,列表中全部是空格,
        self.c.pop()#刪去最後多餘的換行符

        range1=range(self.top,self.bottom+1)
        range2=range(self.left,self.right+1)
        for row,column in product(range1,range2):
        #實現下面語句的功能
        #for row in range1:
        #    for column in range2:
            try:
                data=self.table.item(row,column).text()
                number2=(row-self.top)*(self.column_n+1)+(column-self.left)
                self.c[number2]=data+'\t'
                #計算出單元格的位置,替換掉原來的空格。
            except:
                pass
        self.STR=str()
        for s in self.c:
            self.STR=self.STR+s

    def table_paste(self):
        try:#有時會誤觸ctrl+v,避免報錯,所以就try了
            i=self.index_row
            j=self.index_column
            content=self.table.item(i,j).text()
            b=str()
            for a in content:
                if a!='\n':
                    if a!='\t':
                        b=b+a                        
                    else:
                        item = QTableWidgetItem(b)
                        self.table.setItem(i,j,item)
                        b=''
                        j+=1
                else:
                    item = QTableWidgetItem(b)
                    self.table.setItem(i,j,item)
                    b=''
                    i+=1
                    j=self.index_column
                item = QTableWidgetItem(b)
                self.table.setItem(i,j,item)
        except:
            pass




if __name__=="__main__":
    app=QApplication(sys.argv)
    demo=Demo()
    demo.show()
    sys.exit(app.exec_())

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章