Python PyQt:QTableView+;QSqlTableModel-将所有选定的行或列复制并粘贴到记事本或Excel中

Python PyQt:QTableView+;QSqlTableModel-将所有选定的行或列复制并粘贴到记事本或Excel中,python,pyqt,copy-paste,qtableview,qsqltablemodel,Python,Pyqt,Copy Paste,Qtableview,Qsqltablemodel,首先,我已经看过Ekhumaro关于一个几乎相似主题的代码。然而,当我试图实现这段代码时,我得到了一个不同的结果。它不复制和粘贴所有选定的单元格,而是分别复制选定行的第一个或多个单元格。我需要用户能够选择多个行或列,并将这些值粘贴到excel或记事本中。有什么想法吗 图形用户界面: 代码: from PyQt4 import QtCore, QtGui, QtSql import sys import sqlite3 import time import csv import Sear

首先,我已经看过Ekhumaro关于一个几乎相似主题的代码。然而,当我试图实现这段代码时,我得到了一个不同的结果。它不复制和粘贴所有选定的单元格,而是分别复制选定行的第一个或多个单元格。我需要用户能够选择多个行或列,并将这些值粘贴到excel或记事本中。有什么想法吗

图形用户界面:

代码:

from PyQt4 import QtCore, QtGui, QtSql
import sys  
import sqlite3
import time
import csv


import Search  # This file holds our MainWindow and all design related things

# it also keeps events etc that we defined in Qt Designer
import os 
try:
    from PyQt4.QtCore import QString
except ImportError:
    QString = str

class TableEditor(QtGui.QMainWindow, Search.Search_MainWindow):
    def __init__(self, tableName, parent=None):
        # Explaining super is out of the scope of this article
        # So please google it if you're not familar with it
        # Simple reason why we use it here is that it allows us to
        # access variables, methods etc in the design.py file
        super(self.__class__, self).__init__()
        self.setupUi(self)  # This is defined in design.py file automatically
        # It sets up layout and widgets that are defined
        self.model = QtSql.QSqlTableModel(self)
        self.model.setTable('CAUTI')
        self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
        self.model.select()
        self.model.setHeaderData(0, QtCore.Qt.Horizontal, "MRN")
        self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Last Name")
        self.model.setHeaderData(2, QtCore.Qt.Horizontal, "First Name")
        self.model.setHeaderData(3, QtCore.Qt.Horizontal, "Date of Event")
        self.model.setHeaderData(4, QtCore.Qt.Horizontal, "Facility")
        self.model.setHeaderData(5, QtCore.Qt.Horizontal, "Unit")
        self.model.setHeaderData(6, QtCore.Qt.Horizontal, "User")
        #self.tableView.verticalHeader().setVisible(False)
        self.tableView.setModel(self.model)
        self.setWindowTitle("HAI Table")
        self.tableView.setColumnWidth(0,100)
        self.tableView.setColumnWidth(1,100)
        self.tableView.setColumnWidth(2,100)
        self.tableView.setColumnWidth(3,100)
        self.tableView.setColumnWidth(4,100)
        self.tableView.setColumnWidth(5,100)
        self.tableView.setColumnWidth(6,83)
        self.tableView.setSortingEnabled(True)
        self.tableView.setDropIndicatorShown(True)
        self.tableView.setAcceptDrops(True)
        self.tableView.setDragEnabled(True)
        self.tableView.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.tableView.horizontalHeader().setMovable(True)       
        self.tableView.horizontalHeader().setDragEnabled(True)
        self.clip = QtGui.QApplication.clipboard()

     ## Note: ** When I unblock this line of code, I get an error.
        #self.tableView.installEventFilters(self)




        self.tableView.horizontalHeader().setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.tableView.verticalHeader().setMovable(True)
        self.tableView.verticalHeader().setDragEnabled(True)
        self.tableView.verticalHeader().setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.tableView.setSelectionBehavior(QtGui.QTableView.SelectRows)
        self.submitButton.clicked.connect(self.submit)
        self.revertButton.clicked.connect(self.model.revertAll)
        self.quitButton.clicked.connect(self.close)

        self.tableView.horizontalHeader().setSortIndicatorShown(True)
        self.tableView.horizontalHeader().setClickable(True)
    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.KeyPress and
            event.matches(QtGui.QKeySequence.Copy)):
            self.copySelection()
            return True
        return super(Window, self).eventFilter(source, event)

    def copySelection(self):
        selection = self.tableView.selectedIndexes()
        if selection:
            rows = sorted(index.row() for index in selection)
            columns = sorted(index.column() for index in selection)
            rowcount = rows[-1] - rows[0] + 1
            colcount = columns[-1] - columns[0] + 1
            table = [[''] * colcount for _ in range(rowcount)]
            for index in selection:
                row = index.row() - rows[0]
                column = index.column() - columns[0]
                table[row][column] = index.data()
            stream = io.StringIO()
            csv.writer(stream).writerows(table)
            QtGui.qApp.clipboard().setText(stream.getvalue())

    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDropEnabled    


def main():
    app = QtGui.QApplication(sys.argv)  
    #app.setStyle( "Plastique" )
    db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
    db.setDatabaseName('HAI.db')

    editor = TableEditor('CAUTI')
    editor.show()
    app.exec_()  


if __name__ == '__main__': 
    main()  

您的实现在多个方面被破坏,因此您复制的代码永远不会被执行。因此,将使用表的内置复制函数,该函数不处理多个选定项

我复制多个表项的原始代码是。我认为通过更改以下行,您应该能够使您的示例正常工作:

from PyQt4 import QtCore, QtGui, QtSql
# fix imports
import sys, io
...

class TableEditor(QtGui.QMainWindow, Search.Search_MainWindow):
    def __init__(self, tableName, parent=None):
        # do not ever use self.__class__ here
        super(TableEditor, self).__init__()
        ...
        # install event-filter properly
        self.tableView.installEventFilter(self)

    def eventFilter(self, source, event):
        ...
        # call super properly
        return super(TableEditor, self).eventFilter(source, event)

显然,我无法运行您的实际示例代码,因此可能还有其他我没有发现的错误。

您的实现在多个方面被破坏,因此您复制的代码永远无法执行。因此,将使用表的内置复制函数,该函数不处理多个选定项

我复制多个表项的原始代码是。我认为通过更改以下行,您应该能够使您的示例正常工作:

from PyQt4 import QtCore, QtGui, QtSql
# fix imports
import sys, io
...

class TableEditor(QtGui.QMainWindow, Search.Search_MainWindow):
    def __init__(self, tableName, parent=None):
        # do not ever use self.__class__ here
        super(TableEditor, self).__init__()
        ...
        # install event-filter properly
        self.tableView.installEventFilter(self)

    def eventFilter(self, source, event):
        ...
        # call super properly
        return super(TableEditor, self).eventFilter(source, event)
显然,我无法运行您的实际示例代码,因此可能还有其他我没有发现的错误。

这要快得多:

def copySelection(self):
    clipboardString = StringIO()
    selectedIndexes = self.ui.tableView.selectedIndexes()
    if selectedIndexes:
        countList = len(selectedIndexes)         
        for r in range(countList):
            current = selectedIndexes[r]
            displayText = current.data(QtCore.Qt.DisplayRole)
            if r+1 < countList:
                next_ = selectedIndexes[r+1]
                if next_.row() != current.row():
                    displayText += ("\n")
                else:
                    displayText += ("\t")
            clipboardString.write(displayText)
        pyperclip.copy(clipboardString.getvalue())
def copySelection(自):
clipboardString=StringIO()
SelectedIndex=self.ui.tableView.SelectedIndex()
如果选择了索引:
countList=len(已选索引)
对于范围内的r(计数列表):
当前=所选索引[r]
displayText=current.data(QtCore.Qt.DisplayRole)
如果r+1<计数列表:
下一步=所选索引[r+1]
如果下一行()!=当前行():
displayText+=(“\n”)
其他:
displayText+=(“\t”)
clipboardString.write(显示文本)
pyperclip.copy(clipboardString.getvalue())
这要快得多:

def copySelection(self):
    clipboardString = StringIO()
    selectedIndexes = self.ui.tableView.selectedIndexes()
    if selectedIndexes:
        countList = len(selectedIndexes)         
        for r in range(countList):
            current = selectedIndexes[r]
            displayText = current.data(QtCore.Qt.DisplayRole)
            if r+1 < countList:
                next_ = selectedIndexes[r+1]
                if next_.row() != current.row():
                    displayText += ("\n")
                else:
                    displayText += ("\t")
            clipboardString.write(displayText)
        pyperclip.copy(clipboardString.getvalue())
def copySelection(自):
clipboardString=StringIO()
SelectedIndex=self.ui.tableView.SelectedIndex()
如果选择了索引:
countList=len(已选索引)
对于范围内的r(计数列表):
当前=所选索引[r]
displayText=current.data(QtCore.Qt.DisplayRole)
如果r+1<计数列表:
下一步=所选索引[r+1]
如果下一行()!=当前行():
displayText+=(“\n”)
其他:
displayText+=(“\t”)
clipboardString.write(显示文本)
pyperclip.copy(clipboardString.getvalue())

@ekhuroman,你太棒了!!!非常感谢你为我提供的一切帮助。我无法表达我有多感激=老兄,你太棒了!!!非常感谢你为我提供的一切帮助。我无法表达我有多感激=请注意,此代码已中断,因为它无法正确处理非连续选择。此外,它速度较慢,因为它使用的是
pyperclip
,而不是qt剪贴板。(即使没有
pyperclip
,它也不会运行得更快)。请注意,此代码已被破坏,因为它无法正确处理非连续的选择。此外,它速度较慢,因为它使用的是
pyperclip
,而不是qt剪贴板。(即使没有
pyperclip
,它也不会运行得更快)。