Python PyQt:QTableView+;QSqlTableModel-将所有选定的行或列复制并粘贴到记事本或Excel中
首先,我已经看过Ekhumaro关于一个几乎相似主题的代码。然而,当我试图实现这段代码时,我得到了一个不同的结果。它不复制和粘贴所有选定的单元格,而是分别复制选定行的第一个或多个单元格。我需要用户能够选择多个行或列,并将这些值粘贴到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
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
,它也不会运行得更快)。