python - 按下 "Enter"后 PyQt QItemDelegate setFocus 到 QTableWidget

标签 python python-2.7 pyqt pyqt4 qtablewidget

我正在使用 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_())  

关于python - 按下 "Enter"后 PyQt QItemDelegate setFocus 到 QTableWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52382736/

相关文章:

python - 使用 Opencv 获取轮廓内的平均颜色

从小于数字的列表返回值的Python函数

python - 无法导出到 ".csv"文件 - pandas.DataFrame

Python从py模块读取所有导入语句的简单方法

python - 仅当 QProcess Stdout 包含子字符串时才打印它

python - 从 pyqt 线程内部启动多个线程

python - 如何使用python tesseract仅设置init参数?

python - 使用 pd.apply() 和 shift 来比较相邻行

python - 添加新小部件时,滚动区域无法扩展(滚动)

qt - 在 QtWebView 中捕获链接点击并在默认浏览器中打开