如何在 pyqt5 中新创建的 QTableWidget 单元格中使用自动完成器?

how to have auto-completer in a QTableWidget cell that newly-created in pyqt5?

我正在尝试在我的 table 单元格中使用自动完成器并且它正在工作,但是当我向 table 添加新行时出现问题, 1. 如何将相同的功能添加到新创建的行中? 我使用 _addRow 方法添加新行。 2. 如何将此功能添加到 table 的第二列或第三列? 在这里我使用 self.locs 作为第一列,我需要像 self.tech 这样的东西来匹配第二列。 这是代码:

class TableItemCompleter(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        completionlist = index.data(Qt.UserRole)
        autoCompleter = QCompleter(completionlist,parent)
        autoCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        autoCompleter.setFilterMode(Qt.MatchContains)
        editor.setCompleter(autoCompleter)
        return editor
class TableWidget(QTableWidget):
    def __init__(self, df, action='Edit'):
        super().__init__()
        self.df = df
        self.setStyleSheet('font-size:15px;')
        # Set table dimensions
        rows, cols = self.df.shape
        if action == 'Edit':
            pass
        elif action == 'Append':
            n = 4 # number of rows
            self.setRowCount(n)
            self.setColumnCount(cols)
            self.locs = self.df['LOCATION'].unique().tolist()
            #tech = self.df['TECHNOLOGY'].unique().tolist()

            self.setHorizontalHeaderLabels(list(self.df.columns))
            self.verticalHeader().setDefaultSectionSize(50)
            self.horizontalHeader().setDefaultSectionSize(200)
            self.setItemDelegateForColumn(0, TableItemCompleter())
            #self.setItemDelegateForColumn(TableItemCompleter(), 2)# how can I have it for second col?
            for row in range(n-1):
                for col in range(self.columnCount()):
                    item = QTableWidgetItem('')#str(self.df.tail(n-1).iloc[row,col]))
                    item.setData(Qt.UserRole, self.locs)
                    self.setItem(row, col, item)
                    #self.setItem(row, col, QTableWidgetItem(str(self.df.tail(2).iloc[row,col])))
            self.cellChanged[int, int].connect(self.update_df)
            #self.setItemDelegate(TableItemCompleter())
        else: 
            pass
    
    def _addRow(self):
        rowCount = self.rowCount()
        self.insertRow(rowCount)

谢谢:)

由于模型的每一列的完成字符串列表是相同的,因此在索引上设置该数据没有用处。更好的解决方案是使用基于列的完成“矩阵”来初始化委托。

CompletionKeys = {
    0: 'LOCATION', 
    1: 'TECHNOLOGY', 
    2: ...
}

class TableItemCompleter(QStyledItemDelegate):
    def __init__(self, completionMap, parent=None):
        super().__init__(parent)
        self.completers = {}
        for column, completionList in completionMap.items():
            completer = QCompleter(completionList, self)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setFilterMode(Qt.MatchContains)
            self.completers[column] = completer


    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        if index.column() in self.completers:
            editor.setCompleter(self.completers[index.column()])
        return editor


class TableWidget(QTableWidget):
    def __init__(self, df, action='Edit'):
        super().__init__()
        self.df = df
        self.setStyleSheet('font-size:15px;')
        # Set table dimensions
        rows, cols = self.df.shape
        if action == 'Edit':
            pass
        elif action == 'Append':
            n = 4 # number of rows
            self.setRowCount(n)
            self.setColumnCount(cols)

            self.setHorizontalHeaderLabels(list(self.df.columns))
            self.verticalHeader().setDefaultSectionSize(50)
            self.horizontalHeader().setDefaultSectionSize(200)
            for row in range(n-1):
                for col in range(cols):
                    item = QTableWidgetItem('')
                    self.setItem(row, col, item)

            completionMap = {}
            for col in range(cols):
                key = CompletionKeys.get(col)
                if key:
                    completionMap[col] = self.df[key].unique().tolist()
            self.setItemDelegate(TableItemCompleter(completionMap, self))

            self.cellChanged[int, int].connect(self.update_df)