Focus und Cursor in Table setzen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Nobuddy
User
Beiträge: 859
Registriert: Montag 30. Januar 2012, 16:38

Montag 12. April 2021, 17:39

Hallo zusammen,
ich möchte Focus und Cursor automatisch in ein Datenfeld setzen, wenn das Datenfeld folgender Wert beinhaltet "<?>".

Folgender Code, habe ich zum Testen:

Code: Alles auswählen

import sys
import operator  # used for sorting
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import (Qt, QSize, QEvent, pyqtSignal, QObject,
    QSortFilterProxyModel)
from PyQt5.QtGui import QStandardItem, QStandardItemModel, QCloseEvent, QKeySequence
from PyQt5.QtWidgets import (QMainWindow, QMdiArea, QWidget, QMessageBox, 
    QTableView, QGridLayout, QApplication, QShortcut, qApp,
    QStyledItemDelegate, QCompleter, QLineEdit, QHBoxLayout)


title = 'Backlight management'
header = ['Pos', 'Supplier', 'Artikel', 'Benennung']
dataset = ['001', '<?>', '<?>', 'Bratwurst weiss, 125 g / Stück, 50% Schweinefleisch, 50% Rindfleisch']


class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("MDI demo")
        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)
        self.mdi.pool2dict = {}
        sub = Dataset(self, dataset, header)
        self.mdi.addSubWindow(sub)
        sub.show()


class Dataset(QWidget): 

    def __init__(self, parent, dataset, header): 
        super(Dataset, self).__init__()
        self.parent = parent
        try:
            self.listname = parent.listname
        except AttributeError:
			# Testing, not listname.
            pass
        self.mdi = parent.mdi
        self.dataset = dataset
        self.header = header
        self.setObjectName('DATASET')
        self.installEventFilter(self)
        self.setFocusPolicy(Qt.StrongFocus)
        self.view_dataset = QTableView(self)
        # GridLayout
        grid = QGridLayout() 
        grid.addWidget(self.view_dataset, 0, 0)
        self.setLayout(grid)
        self.model_dataset = QStandardItemModel(self)
        # Vertical header
        [self.model_dataset.setHeaderData(i, Qt.Vertical, column)
            for i, column in enumerate(header)]
        # Load dataset
        [self.model_dataset.invisibleRootItem().appendRow(
            QStandardItem(column)) for column in self.dataset]
        self.proxy = QSortFilterProxyModel(self) 
        self.proxy.setSourceModel(self.model_dataset)
        self.view_dataset.setModel(self.proxy) 
        self.new()

    def new(self):
        self.dataset = [self.model_dataset.invisibleRootItem().child(i).text() 
            for i in range(len(self.header))]
        for i in range(len(self.header)):
            value = self.dataset[i]
            self.model_dataset.item(i, 0).setText(value)
        error_sign = '<?>'
        if set((error_sign,)) & set(self.dataset):
            for value in self.dataset:
                if value == error_sign:
                    print('Eingabefeld muss ausgefüllt werden!')
                    # Setze Focus und Cursor in betreffendes Eingabefeld.
                    # ??????
                    return


def main():
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
Die betreffende Funktion "new", in der Focus und Cursor gesetzt werden soll!
Leider bin ich da total übefordert und kann dies selbst nicht umsetzen, daher hoffe ich auf Eure Hilfe!

Grüße Nobuddy
Nobuddy
User
Beiträge: 859
Registriert: Montag 30. Januar 2012, 16:38

Dienstag 13. April 2021, 14:34

Mir ist gerade aufgefallen, dass das so nicht funktionieren kann.
Das Aufrufen der Funktion "new" innerhalb der Initialisierung ist falsch.
Wollte abkürzen ... normalerweise, wird die Funktion "new" durch betätigen eines Buttons ausgelöst.
In der Funktion "new" , soll unter anderem fehlende Pflicheingaben erkannt werden.
Diese Eingabefelder, haben den Wert "<?>".
Existiert so eine fehlende Pflichteingabe, soll der Focus auf das betreffende Eingabefeld gesetzt werden.
Würde mich über Eure Hilfe und Tipps freuen, die mich in die richtige Richtung bringen!
Nobuddy
User
Beiträge: 859
Registriert: Montag 30. Januar 2012, 16:38

Freitag 16. April 2021, 12:05

Ich gebe nicht auf, auch wenn ich vermutlich noch weit vom Ziel entfernt bin :wink:
Ich poste hier mal meinen neuen Ansatz.
Das betreffende Feld, wird farblich markiert, lässt sich aber nicht editieren.
Durch Betätigen der TAB-Taste, findet nochmals eine Farbänderung statt und es sieht aus, dass das Bearbeitungsfeld editiert werden kann.
Überraschenderweise, wird das erste Feld des Datensatzes bei Texteinagbe editiert.
Hoffe, Ihr könnt mir dabei weiterhelfen und mir einen Schubs in die richtige Richtung geben!

Code: Alles auswählen

    def new(self):
        self.dataset = [self.model_dataset.invisibleRootItem().child(i).text() 
            for i in range(len(self.header))]
        for i in range(len(self.header)):
            value = self.dataset[i]
            self.model_dataset.item(i, 0).setText(value)
        error_sign = '<?>'
        if set((error_sign,)) & set(self.dataset):
            for i, value in enumerate(self.dataset):
                if value == error_sign:
                    print('Eingabefeld muss ausgefüllt werden!')
                    index = self.model_dataset.item(i, 0).index()
                    print('index: ', index)
                    self.selectionModel.select(index, QItemSelectionModel.Select)
Nobuddy
User
Beiträge: 859
Registriert: Montag 30. Januar 2012, 16:38

Donnerstag 29. April 2021, 14:58

Auch wenn ich keine Resonanz zu meinem Anliegen erhalten habe, möchte ich doch mein jetziges Ergebnis posten.
#!/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()

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 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.lower()
value = self.dataset
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()
Antworten