PyQt:如何在QTableView中的光标处插入文本 [英] PyQt: How to insert text at the cursor in QTableView

查看:357
本文介绍了PyQt:如何在QTableView中的光标处插入文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QTableView如下.我想按下测试"按钮并在光标处插入一个"a",例如在(行,列)=(2,2)处的"11"中间.即,用户双击单元格(2,2)并将光标置于"11"的中间,然后按Test.所需结果:"1a1".

I have a QTableView as below. I'd like to press the Test button and insert an "a" at the cursor - for example in the middle of "11" at (row,column) = (2,2). That is, the user double-clicks cell (2,2) and places the cursor in the middle of "11", and presses Test. Desired result: "1a1".

这可行吗?如果是,怎么办?非常感谢.

Is this doable? If yes, how? Thanks very much.

# coding: utf-8

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *

MY_ARRAY = [['00', '01', '02'],
            ['10', '11', '12'],
            ['20', '21', '22']]


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

        self.tablemodel = MyTableModel(MY_ARRAY)

        self.tableview = QTableView()

        self.tableview.setModel(self.tablemodel)

        self.tableview.setItemDelegate(MyDelegate(self))

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.tableview)

        self.button1 = QPushButton("Test")

        self.button1.released.connect(self.test)

        self.layout.addWidget(self.button1)
        self.setLayout(self.layout)

    def test(self):

        # MY_ARRAY.append([30,31,32])

        index = self.tableview.currentIndex()
        item = self.tablemodel.data(index, Qt.DisplayRole)

        print("item %s " % item)

        item_edit = self.tableview.edit(index)

        qDebug("qDebug: item_edit %s " % item_edit)

        MY_ARRAY.insert(index.row(), ['30', '31', '32'])

        self.tablemodel.layoutChanged.emit()

        qDebug(" {} " .format(MY_ARRAY))

        qcursor = QCursor.pos()
        qDebug(" {} ".format(qcursor))

        qcursor1 = self.mapFromGlobal(qcursor)
        qDebug(" {} ".format(qcursor1))

        # qDebug(" self.tableview.indexAt(qcursor) {} ".format(self.tableview(qcursor)))
        # qDebug(" self.tableview.indexAt(qcursor1) {} ".format(self.tableview(qcursor1)))

        # print(' index.row(): ', index.row())

        qDebug(
            " tableview.rowViewportPosition %s " %
            self.tableview.rowViewportPosition(index.row()))
        qDebug(
            " tableview.columnViewportPosition %s " %
            self.tableview.columnViewportPosition(index.column()))

        # qDebug(" tableview.viewport() %s " % self.tableview.viewport(qcursor))

        item = self.tableview.setCurrentIndex(index)
        qDebug(" tableview.item() %s " % self.tableview)


class MyTableModel(QAbstractTableModel):
    def __init__(self, datain, parent=None, *args):
        super(MyTableModel, self).__init__(parent, *args)

        self.arraydata = datain

    def rowCount(self, parent):
        return len(self.arraydata)

    def columnCount(self, parent):
        return len(self.arraydata[0])

    def data(self, index, role):
        if not index.isValid():
            return None

        elif not (role == Qt.DisplayRole or role == Qt.EditRole):
            return None
        return (self.arraydata[index.row()][index.column()])

    def setData(self, index, value, role=Qt.EditRole):
        self.arraydata[index.row()][index.column()] = value
        return True

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


class MyDelegate(QStyledItemDelegate):

    def __init__(self, parent=None):
        super(MyDelegate, self).__init__(parent)

    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        self.connect(editor, SIGNAL("returnPressed()"),
                     self.commitAndCloseEditor)
        return editor

    def commitAndCloseEditor(self):
        editor = self.sender()
        if isinstance(editor, (QTextEdit, QLineEdit)):
            self.emit(SIGNAL("commitData(QWidget*)"), editor)
            self.emit(SIGNAL("closeEditor(QWidget*)"), editor)

    def setEditorData(self, editor, index):
        text = index.model().data(index, Qt.DisplayRole)

        editor.setText(text)

    def setModelData(self, editor, model, index):
        model.setData(index, editor.text())

def main():
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

推荐答案

经过qDebug的艰苦努力和使用,我终于设法找到了解决方案.我相信它可以进一步改善.但是我对PyQt不太了解.这个想法是在关闭编辑器之前将光标位置缓存在MyDelegate(QStyledItemDelegate)中.我希望它对遇到相同问题的人有用.

After a lot of struggle and uses of qDebug I finally managed to find a solution. I am sure it can be further improved. But I don't know much about PyQt. The idea is to cache the cursor position in MyDelegate(QStyledItemDelegate) before the editor is closed. I hope it can be useful to someone who encounters the same problem.

class MyDelegate(QStyledItemDelegate):
    ...
    def createEditor(self, parent, option, index):
        self.cursorpos = -1  # unset flag
        editor = QLineEdit(parent)
        self.connect(editor, SIGNAL("editingFinished()"),
                         self.commitAndCloseEditor)
        return editor

    def commitAndCloseEditor(self):
        editor = self.sender()
        self.cursorpos = editor.cursorPosition()
        if isinstance(editor, (QTextEdit, QLineEdit)):
            self.emit(SIGNAL("commitData(QWidget*)"), editor)
            self.emit(SIGNAL("closeEditor(QWidget*)"), editor)

下面是整个内容.

# coding: utf-8

import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *

MY_ARRAY = [['00', '01', '02'],
            ['10', '11', '12'],
            ['20', '21', '22']]


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

        self.tablemodel = MyTableModel(MY_ARRAY)

        self.tableview = QTableView()

        self.tableview.setModel(self.tablemodel)

        # self.tableview.setItemDelegate(MyDelegate(self))

        self.delegate = MyDelegate(self)
        self.tableview.setItemDelegate(self.delegate)

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.tableview)

        self.button1 = QPushButton("Test")

        self.button1.released.connect(self.test)

        self.layout.addWidget(self.button1)
        self.setLayout(self.layout)

    def test(self):

        index = self.tableview.currentIndex()
        item = self.tablemodel.data(index, Qt.DisplayRole)

        qDebug("item %s " % item)

        qDebug(" <test><MyDelegateMyDelegate> self.delegate.cursorpos: %s " % self.delegate.cursorpos)

        cursorpos = self.delegate.cursorpos
        qDebug(" <test> cursor pos %s " % cursorpos)
        if cursorpos > -1:
            index.model().setData(index, item[:cursorpos] + ' foo ' + item[cursorpos:])
            self.tablemodel.layoutChanged.emit()
            self.delegate.cursorpos = -1


class MyTableModel(QAbstractTableModel):
    def __init__(self, datain, parent=None, *args):
        super(MyTableModel, self).__init__(parent, *args)

        self.arraydata = datain

    def rowCount(self, parent):
        return len(self.arraydata)

    def columnCount(self, parent):
        return len(self.arraydata[0])

    def data(self, index, role):
        if not index.isValid():
            return None

        elif not (role == Qt.DisplayRole or role == Qt.EditRole):
            return None
        return (self.arraydata[index.row()][index.column()])

    def setData(self, index, value, role=Qt.EditRole):
        self.arraydata[index.row()][index.column()] = value
        return True

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


class MyDelegate(QStyledItemDelegate):

    def __init__(self, parent=None):
        super(MyDelegate, self).__init__(parent)
        self.cursorpos = -1  # unset flag

    def createEditor(self, parent, option, index):
        self.cursorpos = -1  # unset flag
        editor = QLineEdit(parent)
        self.connect(editor, SIGNAL("editingFinished()"),
                         self.commitAndCloseEditor)
        return editor

    def commitAndCloseEditor(self):
        editor = self.sender()
        self.cursorpos = editor.cursorPosition()
        if isinstance(editor, (QTextEdit, QLineEdit)):
            self.emit(SIGNAL("commitData(QWidget*)"), editor)
            self.emit(SIGNAL("closeEditor(QWidget*)"), editor)

    def setEditorData(self, editor, index):
        text = index.model().data(index, Qt.DisplayRole)

        editor.setText(text)


    def setModelData(self, editor, model, index):
        model.setData(index, editor.text())

def main():
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

这篇关于PyQt:如何在QTableView中的光标处插入文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆