zur Bearbeitung eines Datensatzes aus einer Tabelle, verwende ich eine vertikalen Ausgabe.
Bestimmte Positionen, dürfen nicht verändert werden, dazu verwende ich als Beispiel ein Dictionary mit Namen 'writeLock'. Mit den Richtungstasten Up, Down und der Tab-Taste, werden die betreffenden Felder übersprungen.
Mit der linken Maustaste, habe ich noch keine Lösung gefunden, da beim Auslösen der Maustaste im eventFilter, kein Event stattfindet.
Ich hoffe, Ihr könnt mir bei Lösung dieses Problems helfen!
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# For Python3.x
import sys
from PyQt5.QtCore import (Qt, QEvent, QSize)
from PyQt5.QtGui import (QMouseEvent)
from PyQt5.QtWidgets import (QApplication, QTableWidget, QTableWidgetItem, 
    QLineEdit, QMainWindow, QMdiArea, QVBoxLayout, QWidget)
title = 'Backlight management'
header = ['Pos', 'Supplier', 'Artikel', 'Benennung']
dataset = ['001', '<?>', '<?>', 'Bratwurst weiss, 125 g / Stück, 50% Schweinefleisch, 50% Rindfleisch']
write_lock = {}
write_lock = {0 : True}
write_lock = {0 : True, 2 : True}
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("MDI demo")
        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)
        self.mdi.pool2dict = {}
        self.write_lock = write_lock
        sub = Dataset(self, dataset, header)
        self.mdi.addSubWindow(sub)
        sub.show()
class Dataset(QWidget): 
    def __init__(self, parent, dataset, header): 
        super().__init__()
        self.parent = parent
        self.mdi = parent.mdi
        self.dataset = dataset
        self.header = header
        self.write_lock = parent.write_lock
        self.setObjectName('DATASET')
        self.setFocusPolicy(Qt.StrongFocus)
        self.setMouseTracking(True)
        self.width = self.columnWidth()
        self.createDataset()
        # Layout
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget)
        self.setLayout(self.layout)
        self.selectionModel = self.tableWidget.selectionModel()
        # eventFilter
        self.tableWidget.installEventFilter(self)
        
        self.checkDataset()
    def sizeHint(self):
        try:
            self.width_qs
        except AttributeError: 
            # and the margins which include the frameWidth and the extra
            # margins that would be set via a stylesheet or something else
            margins = self.contentsMargins()
            # y
            height = self.fontMetrics().height()
            height += height * len(self.header)
            height += self.tableWidget.horizontalScrollBar().height()
            height += margins.left() + margins.right()
            # x
            width = self.tableWidget.verticalHeader().length()
            width += self.tableWidget.horizontalHeader().length()
            width += self.tableWidget.verticalScrollBar().width()
            width += margins.left() + margins.right()
            self.width_qs = round(width * 1.1)
            self.height_qs = round(height * 1.7)
        return QSize(self.width_qs, self.height_qs) 
    
    def columnWidth(self):
        md = dict([(len(value), value) for value in self.dataset])
        mv = md[max(md)]
        width = round(
            QLineEdit().fontMetrics().boundingRect(mv).width() * 1.1)
        if width < 500:
            width = 500
        return width
    def eventFilter(self, source, event):
        """
        View events and check for taskstype.
        """
        keyWork = False
        try:    
            if event.type() == QEvent.MouseButtonRelease:
                print('##### MouseButtonRelease')
            if event.button() == Qt.LeftButton:
                print('##### LeftButton')
                if event.type() == QEvent.MouseButtonPress:
                    pass
        except AttributeError:
            pass
        try:
            if event.type() == QEvent.KeyRelease:
                if event.key() == Qt.Key_Tab:
                    keyWork = 'key_tab'
                elif event.key() == Qt.Key_Up:
                    keyWork = 'key_up'
                elif event.key() == Qt.Key_Down:
                    keyWork = 'key_down'
                if keyWork:
                    self.writeLockCheck(keyWork)
        except AttributeError:
            pass
        if event.type() == QEvent.FocusIn:
            keyWork = 'focus_in'
            self.writeLockCheck(keyWork)
        return super().eventFilter(source, event)
        
    def writeLockCheck(self, keyWork):
        """
        Set the FOCUS to the next input field without write protection. 
        """
        i = self.tableWidget.currentRow()
        while True:
            tableItem = self.tableWidget.cellWidget(i, 0)
            try:
                tableItem.setFocus()
            except AttributeError:
                pass
            try:
                tableItem.selectAll()
            except AttributeError:
                pass
            if not self.write_lock.get(i):
                break
            if i < (len(self.header) - 1):
                if keyWork == 'key_up':
                    i -= 1
                    if i < 0:
                        while True:
                            i += 1
                            if not self.write_lock.get(i):
                                break
                else:
                    i += 1
            elif i == (len(self.header) - 1):
                i = 0
        return
    
    def createDataset(self):
        """
        Create data record vertical. 
        """
        self.tableWidget = QTableWidget()
        # Row count
        self.tableWidget.setRowCount(len(self.dataset)) 
        # Column count
        self.tableWidget.setColumnCount(1)  
        for i, value in enumerate(self.dataset):
            self.column_name = self.header[i].lower()
            value = self.dataset[i]
            self.tableWidget.setVerticalHeaderItem(i, 
                QTableWidgetItem(self.header[i]))
            tableItem = QLineEdit()
            tableItem.setText(value)
            tableItem.setFixedWidth(self.width)
            self.tableWidget.setCellWidget(i, 0, tableItem)
        return
    def checkDataset(self):
        """
        Check record and recognize mandatory fields. 
        """
        dataset = [self.tableWidget.cellWidget(i, 0).text()
            for i in range(len(self.header))]
        for i in range(len(self.header)):
            self.column_name = self.header[i].lower()
            value = self.dataset[i]
            tableItem = QLineEdit()
            tableItem.setText(value)
            tableItem.setFixedWidth(self.width)
            self.tableWidget.setCellWidget(i, 0, tableItem)
        error_sign = '<?>'
        if set((error_sign,)) & set(dataset):
            for i, value in enumerate(dataset):
                if value == error_sign:
                    widget = self.tableWidget.cellWidget(i, 0)
                    widget.setFocus()
                    widget.selectAll()
                    self.mdi.duty_error = True
                    work_info = 'Eingabefeld muss ausgefüllt werden!'
                    self.mdi.work_info = work_info
                    print(work_info)
                    break
        self.dataset = dataset
        return
def main():
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())
if __name__ == '__main__':
    main()