2013年9月25日水曜日

PyQt QTableWidget: Copy and Past Excel interface

I made some copy and paste interface between QTableWidget and Excel sheet (only text).

The clipboard interface in PyQt4 can be acquired by
clip = QtGui.QApplication.clipboard()
clip.setText("hoge")
text = clip.text()

In QTableWidget, text in a cell can be acquired by
item(r,c).text()
this returns Qstring and has to be converted to str if you want.

A text can be set to a cell by
setItem(row, column, QtGui.QTableWidgetItem(text))


In Excel, copied cells are splitted by '\t' for columns and '\n' for rows.
The whole program gets like below.
Only the first selected range can be recognized in this example.
The error handling can be better.

Anyways, I hope this helps.

from PyQt4 import QtGui, QtCore
import sys

class MainWindow(QtGui.QMainWindow):
	def __init__(self):
		super(MainWindow, self).__init__()
		self.table = QtGui.QTableWidget(10,5)
		self.clip = QtGui.QApplication.clipboard()

		self.setCentralWidget(self.table)
		self.move(30,30)

	def keyPressEvent(self, e):
		if (e.modifiers() & QtCore.Qt.ControlModifier):
			selected = self.table.selectedRanges()
				
			if e.key() == QtCore.Qt.Key_V:#past
				first_row = selected[0].topRow()
				first_col = selected[0].leftColumn()
				
				#copied text is split by '\n' and '\t' to paste to the cells
				for r, row in enumerate(self.clip.text().split('\n')):
					for c, text in enumerate(row.split('\t')):
						self.table.setItem(first_row+r, first_col+c, QtGui.QTableWidgetItem(text))

			elif e.key() == QtCore.Qt.Key_C: #copy
				s = ""
				for r in xrange(selected[0].topRow(),selected[0].bottomRow()+1):
					for c in xrange(selected[0].leftColumn(),selected[0].rightColumn()+1):
						try:
							s += str(self.table.item(r,c).text()) + "\t"
						except AttributeError:
							s += "\t"
					s = s[:-1] + "\n" #eliminate last '\t'
				self.clip.setText(s)

def main(args):
    app = QtGui.QApplication(sys.argv)
    form = MainWindow()
    form.show()
    
    sys.exit(app.exec_())

    
    
if __name__ == "__main__":
    main(sys.argv)





0 件のコメント:

コメントを投稿