如何以选项卡分隔的字符串格式将 QtableView 单元格内容复制到剪贴板?

问题描述

我有一个在 Qt 中使用 构建的表,其模型由 构建,该模型从 获取数据。我希望能够使用全局剪贴板复制和粘贴单元格的内容。我在 PyQt4 和其他人中找到了几个例子 hereherehere 但是,我仍然无法将任何内容写入剪贴板。我的方法感觉有点蛮力,所以我希望有一种更 Python 化的 Qt'esk 方法

这是我的表类:

class MyTableView(QTableView):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)

    def send_to_clipboard(self):
        # get selected contents from clipboard: List[QModelIndex]
        cells = self.selectedindexes()
        # check for contents
        if not cells:
            return
        # set initial values to first cell
        r = cells[0].row()
        c = cells[0].column()
        text = cells[0].data()
        # skip first cell and iterate over rest to make tab delineated content
        for i in range(len(cells) - 1):
            if cells[i+1].row() == r:
                text += f'\t{cells[i+1].data()}'
                continue
            r += 1
            text += '\n'
        # send text to clipboard
        clipboard = QApplication.instance().clipboard()
        clipboard.clear()
        # strip trailing \n for data set and post to clipboard
        clipboard.setText(text.strip())

    def get_from_clipboard(self):
        # pull clipboard data and split into rows
        clipboard = QApplication.clipboard()
        rows = clipboard.text().split('\n')
        # and split again into column data
        row_col_data = [[data for data in row.split('\t')] for row in rows]
        # get past location and populate with data
        r = self.currentRow()
        c = self.currentColumn()
        for row in row_col_data:
            for data in row:
                self.setItem(r,c,QTableWidgetItem(data))
                self.model()
                c += 1
            r += 1

    def keyPressEvent(self,e: QtGui.QKeyEvent) -> None:
        super().keyPressEvent(e)
        if e.key() == Qt.Key_C and (e.modifiers() & Qt.ControlModifier):
            self.send_to_clipboard()
        elif e.key() == Qt.Key_V and (e.modifiers() & Qt.ControlModifier):
            self.get_from_clipboard()

这是我的模型:

class DataFrameModel(QAbstractTableModel):
    DtypeRole = Qt.UserRole + 1000
    ValueRole = Qt.UserRole + 1001

    def __init__(self,df=pd.DataFrame(),parent=None):
        super(DataFrameModel,self).__init__(parent)
        self._dataframe = df
        self.editable = False

    def setDataFrame(self,dataframe):
        self.beginResetModel()
        self._dataframe = dataframe.copy()
        self.endResetModel()

    def dataFrame(self):
        return self._dataframe

    dataFrame = pyqtProperty(pd.DataFrame,fget=dataFrame,fset=setDataFrame)

    @pyqtSlot(int,Qt.Orientation,result=str)
    def headerData(self,section: int,orientation: Qt.Orientation,role: int = Qt.displayRole):
        if role == Qt.displayRole:
            if orientation == Qt.Horizontal:
                return self._dataframe.columns[section]
            else:
                return str(self._dataframe.index[section])
        return QVariant()

    def rowCount(self,parent=QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._dataframe.index)

    def columnCount(self,parent=QModelIndex()):
        if parent.isValid():
            return 0
        return self._dataframe.columns.size

    def data(self,index,role=Qt.displayRole):
        if not index.isValid() or not (0 <= index.row() < self.rowCount()
                                       and 0 <= index.column() < self.columnCount()):
            return QVariant()
        row = self._dataframe.index[index.row()]
        col = self._dataframe.columns[index.column()]
        dt = self._dataframe[col].dtype

        val = self._dataframe.iloc[row][col]
        if role == Qt.displayRole:
            return str(val)
        if role == DataFrameModel.ValueRole:
            return val
        if role == DataFrameModel.DtypeRole:
            return dt
        if role == Qt.ToolTipRole:
            return str(val)
        if role == Qt.EditRole:
            return str(val)
        return QVariant()

    def roleNames(self):
        roles = {
            Qt.displayRole: b'display',DataFrameModel.DtypeRole: b'dtype',DataFrameModel.ValueRole: b'value',Qt.ToolTipRole: b'tooltip'
        }
        return roles

    def setData(self,value,role: int = Qt.EditRole):
        if not index.isValid() or role != Qt.EditRole:
            return False
        row = index.row()
        if row < 0 or row >= len(self._dataframe.values):
            return False
        column = index.column()
        if column < 0 or column >= self._dataframe.columns.size:
            return False

        self._dataframe.iloc[row][column] = value
        self.dataChanged.emit(index,index)
        return True

    def flags(self,index):
        flags = super(self.__class__,self).flags(index)
        flags |= Qt.ItemIsSelectable
        if self.editable:
            flags |= Qt.ItemIsEditable
            flags |= Qt.ItemIsEnabled
            flags |= Qt.ItemIsDragEnabled
            flags |= Qt.ItemIsDropEnabled
        return flags

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)