Für die Bearbeitung von Datensätzen aus einer Liste, habe ich unten folgenden Code erstellt.
Dieser ist lauffähig, um ihn testen zu können.
Mein Problem ist, dass bei bestimmten Ereignissen, der Focus auf das betreffende Item gesetzt werden soll. Siehe dazu die Funktion "self.VerificationCompulsoryEntryFields".
Leider konnte ich noch keine Lösung finden, die auch bei mir funktioniert hätte.
Daher würde ich mich sehr über Eure Hilfe freuen!
Code: Alles auswählen
import sys
import datetime
date_now = datetime.date.today()
date_time = datetime.datetime.now().strftime('%Y.%m.%d_%H:%M:%S')
from PyQt5.QtCore import Qt, QEvent, QSize, QSortFilterProxyModel
from PyQt5.QtGui import QColor, QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (QAction, QApplication, QGridLayout,
QHeaderView, QLineEdit, QMainWindow, QMdiArea,
QMessageBox, QPushButton, QTableView)
title = 'Backlight management'
listname = 'addresses'
header = ['client', 'client_number', 'supplier_number',
'namen', 'zusatz', 'anrede2', 'namen2', 'info_namen',
'street', 'plz', 'ort', 'entfernung', 'homepage',
'ust_nr', 'steuer_nr', 'handelsregister', 'handelsregister_nr', 'datum']
dataset = ['CUSTOMER', '029002', '', '','', '', '','', 'DIRE STREET 15',
'04711', 'CRAZY CITY', '0', '', '', '', '', '', '2019.03.22']
write_lock = {0 : True, 1 : True}
duty_fields = {0 : True, 1 : True, 3 : True, 8 : True, 9 : True, 10 : True}
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("MDI demo")
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
self.mdi.tileSubWindows()
self.listname = listname
sub = Dataset(self, dataset, header)
self.mdi.addSubWindow(sub)
sub.show()
class Dataset(QLineEdit):
def __init__(self, parent, dataset, header):
super(Dataset, self).__init__()
self.parent = parent
self.old_dataset = self.dataset = dataset
self.header = header
self.mdi = parent.mdi
self.listname = parent.listname
self.write_lock = write_lock
self.duty_fields = duty_fields
self.error_sign = '<?>'
self.installEventFilter(self)
self.setFocusPolicy(Qt.StrongFocus)
self.view = QTableView(self)
self.width = self.columnWidth()
if self.width < 500:
self.width = 500
self.bt1 = QPushButton('Save_close', self)
self.bt1.clicked.connect(self.save_close)
# GridLayout
grid = QGridLayout()
grid.addWidget(self.view, 0, 0)
grid.addWidget(self.bt1, 1, 0)
self.setLayout(grid)
self.model = QStandardItemModel()
# Load and check dataset
self.VerificationCompulsoryEntryFields (self.createDataset())
# Vertical header
[self.model.setHeaderData(i, Qt.Vertical, column)
for i, column in enumerate(header)]
self.proxy = QSortFilterProxyModel(self)
self.proxy.setSourceModel(self.model)
self.view.setModel(self.proxy)
self.view.horizontalHeader().setSectionResizeMode(
0, QHeaderView.Stretch)
def sizeHint(self):
# 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 = round(self.fontMetrics().height() * 1.1)
height += self.view.verticalHeader().length()
height += self.view.horizontalHeader().height()
height += self.view.horizontalScrollBar().height()
height += margins.left() + margins.right()
# x
width = self.view.horizontalHeader().length()
width += self.view.verticalHeader().width()
width += self.view.verticalScrollBar().width()
width += margins.left() + margins.right()
if width < self.width:
width = self.width
return QSize(width, height)
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.KeyRelease:
c = 1
if event.key() == Qt.Key_Tab:
keyWork = 'key_tab'
elif event.key() == Qt.Key_Up:
keyWork = 'key_up'
c = -1
elif event.key() == Qt.Key_Down:
keyWork = 'key_down'
if keyWork:
i = self.view.currentIndex().row() - c
self.checkItem(i)
#self.writeLockCheck(keyWork)
except AttributeError:
pass
return super().eventFilter(source, event)
def valueFormat(self, i):
self.column_name = self.header[i].lower()
#return SetValue(self)
def checkItem(self, i):
item = self.model.invisibleRootItem().child(i)
self.value = item.text()
#self.valueFormat(i)
item.setText(self.value)
item.setData(i, Qt.UserRole)
try:
self.duty_fields[i]
if item.text() == '' or item.text() == self.error_sign:
# item compulsory entry is not true text color is red
if item.text() == '':
item.setText(self.error_sign)
item.setData(QColor(255,0,0), Qt.ForegroundRole)
except KeyError:
pass
try:
self.write_lock[i]
# item read-only, set flags
item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled )
# item read-only, text color is red
item.setData(QColor(255,0,0), Qt.ForegroundRole)
except KeyError:
if item.text() != self.error_sign:
# item compulsory entry is true, text color is white
item.setData(QColor(255,255,255), Qt.ForegroundRole)
item.data(Qt.UserRole)
self.model.setItem(i, 0, item)
return item
def createDataset(self):
[self.model.invisibleRootItem().appendRow(QStandardItem(value))
for i, value in enumerate(self.dataset)]
return self.checkDataset()
def checkDataset(self):
return [self.checkItem(i).text() for i in range(len(self.header))]
def VerificationCompulsoryEntryFields (self, dataset):
self.mdi.duty_error = False
if set((self.error_sign,)) & set(dataset):
self.mdi.duty_error = True
for i, value in enumerate(dataset):
if self.checkItem(i).text() == self.error_sign:
#item.setFocus() # set focus to item, no function
#item.selectAll() # no function
break
work_info = 'Eingabefeld muss ausgefüllt werden!'
self.mdi.work_info = work_info
print(work_info)
return
self.dataset = dataset
return True
def updateDataset(self):
# update model table
self.parent.model.data = sorted(self.parent.model.data)
self.parent.view.setModel(self.mdi.model)
self.parent.model.layoutChanged.emit()
def save_close(self):
if self.VerificationCompulsoryEntryFields (self.checkDataset()):
self.parent.model.data[self.parent.index] = self.dataset
self.updateDataset()
def main():
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()