简体   繁体   中英

How to get delegate item when QTableView is clicked

The code below creates the single QTableView . There is a QItemDelegate is assigned as a PersistentEditor. There are two kind of editors created: QLineEdit is created for the column 0 and the 'QComboBox` is created for the column 1.

When the tableView is clicked I would like to get the instance of both editors: the instance of the LineEdit and the instance of comboBox. How to achieve this?

from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])

class Delegate(QtGui.QItemDelegate):
    def __init__(self):
        QtGui.QItemDelegate.__init__(self)

    def createEditor(self, parent, option, index):
        if index.column()==0:
            lineedit=QtGui.QLineEdit(parent)
            return lineedit

        elif index.column()==1:
            combo=QtGui.QComboBox(parent)
            return combo

    def setEditorData(self, editor, index):
        row = index.row()
        column = index.column()
        value = index.model().items[row][column]
        if isinstance(editor, QtGui.QComboBox):
            editor.addItems(['Somewhere','Over','The Rainbow'])
            editor.setCurrentIndex(index.row())
        if isinstance(editor, QtGui.QLineEdit):
            editor.setText('Somewhere over the rainbow')

class Model(QtCore.QAbstractTableModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)
        self.items = [[1, 'one', 'ONE'], [2, 'two', 'TWO'], [3, 'three', 'THREE']]

    def flags(self, index):
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
    def rowCount(self, parent=QtCore.QModelIndex()):
        return 3 
    def columnCount(self, parent=QtCore.QModelIndex()):
        return 3

    def data(self, index, role):
        if not index.isValid(): return 
        row = index.row()
        column = index.column()
        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            return self.items[row][column]


def tableViewClicked(index):
    print 'clicked indedx:  %s'%index

tableModel=Model()
tableView=QtGui.QTableView() 
tableView.setModel(tableModel)
tableView.setItemDelegate(Delegate())
tableView.clicked.connect(tableViewClicked)

for row in range(tableModel.rowCount()):
    for column in range(tableModel.columnCount()):
        index=tableModel.index(row, column)
        tableView.openPersistentEditor(index)

tableView.show()
app.exec_()

I recently set up something similar like this. This might be what you were after.

Step 1 , create the delegate to do whatever it is you need, and store the QLineEdit as a variable. In the case below, I want a signal to emit every time the user leaves the QLineEdit .

class LineEditDelegate(QtWidgets.QStyledItemDelegate):
    on_focus_out = QtCore.Signal(object)

    def __init__(self, *args, **kwargs):
        super(LineEditDelegate, self).__init__(*args, **kwargs)
        self.line_edit = None

    def createEditor(self, parent, option, index):
        self.line_edit = QtWidgets.QLineEdit(parent=parent)

        self.line_edit.destroyed.connect(lambda: self._line_edit_left(index=index))

        return self.line_edit

    def _line_edit_left(self, index):
        """
        Triggers when line edit was closed / destroyed

        :param index: QModelIndex, index of edited item

        :return: None
        """

        self.on_focus_out.emit(index)

        return

Step 2 , Create you QTableWidget and setup however you want, adding the delegate where you need it. In this example, on all items in column 0

self.table = QtWidgets.QTableWidget(parent=self.base_widget)
self.table.setRowCount(2)
self.table.setColumnCount(2)

self.line_edit_delegate = LineEditDelegate(self.main_window)
self.table.setItemDelegateForColumn(0, self.line_edit_delegate)

I also connect my function to the signal, fulfilling the purpose of this delegate .

self.line_edit_delegate.on_focus_out.connect(self._check_text)

Step 3 , Getting the delegate item, ie the QLineEdit . First you'll need to get the item; you can do this in many ways such as:

item_0 = self.table.currentRow()
item_0 = self.table.currentItem()

or connecting through one of the QTableWidget 's signals that pass through the QTableWidgetItem , row, or whatever:

self.table.itemClicked.connect(self.item_clicked)
self.table.itemDoubleClicked.connect(self.item_double_clicked)

Then with the QTableWidgetItem you can get the delegate , and then get the QLineEdit .

delegate = self.table.itemDelegate(self.table.indexFromItem(item_0))
delegate.line_edit

For my use , I wanted the user to add a new row and then have the QLineEdit get automatically selected for editing. This is what I used:

row_position = self.table.currentRow() + 1

item_0 = QtWidgets.QTableWidgetItem()
item_0.setFont(font)
self.table.setItem(row_position, 0, item_0)

self.table.openPersistentEditor(item_0)
delegate = self.table.itemDelegate(self.table.indexFromItem(item_0))
delegate.line_edit.setFocus()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM