PyQt QItemDelegate setFocus to QTableWidget after "Enter" is pressed

PyQt QItemDelegate setFocus to QTableWidget after "Enter" is pressed

我正在使用 QTableWidget 创建类似 excel 的内容。 QTableWidget 列之一能够让用户用多行更新注释。在使用QTextEdit之前,用户需要手动添加“\n”来实现多行,但这对用户来说并不友好。我发现我可以将 QTextEdit 设置为 QTableWidget。通过使用 QTextEdit,我可以通过按 "Enter" 或 "Shift+Enter" 来键入多行。但是,我希望当按下 "Shift+Enter" 时,它转到下一行但是当按下 "Enter" 时,它 运行 self.update_MySQL 函数。

下面是我的示例代码

import sys, itertools, sip
sip.setapi('QVariant',2)
from PyQt4 import QtCore, QtGui

class CustomTextEditDelegate(QtGui.QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QtGui.QTextEdit(parent)
        return editor

    def setEditorData(self, editor, index):
        editor.setText(index.data())

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

class PIX_DATABASE_UI(QtGui.QTableWidget):
    def __init__(self, parent=None):
        super(PIX_DATABASE_UI, self).__init__(parent)

        ### signal
        self.update_tableWidget()
        self.itemEntered.connect(self.update_MySQL)

    # -----------------------------------------------------------------------------------------------------------------#
    def update_MySQL(self):
        print "MySQL Updated"

    def update_tableWidget(self):
        self.filter_columns = [u'remark']
        self.setColumnCount(len(self.filter_columns))
        self.setHorizontalHeaderLabels(self.filter_columns)
        self.setRowCount(5)

        for row, col in itertools.product(range(5), range(len(self.filter_columns))):
            if self.filter_columns[col] == "remark":
                width = self.sizeHint().width()
                self.setColumnWidth(col, width * 0.75)
                self.setItem(row, col, QtGui.QTableWidgetItem(str("ABC")))
                self.setItemDelegateForColumn(col, CustomTextEditDelegate(self))
                self.verticalHeader().setResizeMode(row, QtGui.QHeaderView.ResizeToContents)

# -----------------------------------------------------------------------------------------------------------------#
# -----------------------------------------------------------------------------------------------------------------#

if __name__ == '__main__':
    global ui
    try:
        ui.close()
    except:
        pass

    app = QtGui.QApplication(sys.argv)
    app.setStyle(QtGui.QStyleFactory.create("Plastique"))
    # print QtGui.QStyleFactory.keys()

    ui = PIX_DATABASE_UI()
    ui.show()
    sys.exit(app.exec_()) 

结论:

感谢 eyllanesc,代码帮助我通过对 keyPressEvent 的稍微修改来实现我想要实现的目标。即使我按下 "Shift + Enter",原始代码仍然会发出。 下面的代码是我修改的。

def keyPressEvent(self, event):
    modifiers = QtGui.QApplication.keyboardModifiers()
    if modifiers != QtCore.Qt.ShiftModifier and event.key() == QtCore.Qt.Key_Return:
        self.enter.emit()
        # If you do not want a new line uncomment the following
        # return
    super(TextEdit, self).keyPressEvent(event)

所以现在,在 textEdit 中编辑并按 "Enter" 后,它将 运行 self.update_MySQL 并且当按 "Shift + Enter" 时,它将转到下一行。

您可以做的是更新模型的数据,为此必须发出调用 setModelData() 方法的 commitData 信号。

通过这样做你可以使用信号itemChanged()因为项目的数据被修改了。

import sys, itertools, sip
sip.setapi('QVariant',2)
from PyQt4 import QtCore, QtGui

class TextEdit(QtGui.QTextEdit):
    pressed = QtCore.pyqtSignal()
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Return:
            self.pressed.emit()
            # If you do not want a new line uncomment the following
            # return
        super(TextEdit, self).keyPressEvent(event)


class CustomTextEditDelegate(QtGui.QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = TextEdit(parent)
        editor.pressed.connect(self.commitAndCloseEditor)
        return editor

    def setEditorData(self, editor, index):
        editor.setText(index.data())

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

    def commitAndCloseEditor(self):
        editor = self.sender()
        self.commitData.emit(editor)
        # if you want to close the editor uncomment the following
        # self.closeEditor.emit(editor, QtGui.QAbstractItemDelegate.NoHint)

class PIX_DATABASE_UI(QtGui.QTableWidget):
    def __init__(self, parent=None):
        super(PIX_DATABASE_UI, self).__init__(parent)

        ### signal
        self.update_tableWidget()
        self.itemEntered.connect(self.update_MySQL)
        self.itemChanged.connect(self.update_MySQL)

    # -----------------------------------------------------------------------------------------------------------------#
    def update_MySQL(self, it):
        print("MySQL Updated", it.text())

    def update_tableWidget(self):
        self.filter_columns = [u'remark']
        self.setColumnCount(len(self.filter_columns))
        self.setHorizontalHeaderLabels(self.filter_columns)
        self.setRowCount(5)

        for row, col in itertools.product(range(5), range(len(self.filter_columns))):
            if self.filter_columns[col] == "remark":
                width = self.sizeHint().width()
                self.setColumnWidth(col, width * 0.75)
                self.setItem(row, col, QtGui.QTableWidgetItem(str("ABC")))
                self.setItemDelegateForColumn(col, CustomTextEditDelegate(self))
                self.verticalHeader().setResizeMode(row, QtGui.QHeaderView.ResizeToContents)

# -----------------------------------------------------------------------------------------------------------------#
# -----------------------------------------------------------------------------------------------------------------#

if __name__ == '__main__':
    global ui
    try:
        ui.close()
    except:
        pass

    app = QtGui.QApplication(sys.argv)
    app.setStyle(QtGui.QStyleFactory.create("Plastique"))
    # print QtGui.QStyleFactory.keys()

    ui = PIX_DATABASE_UI()
    ui.show()
    sys.exit(app.exec_())