erstelle im MDI mit QTableView meine Tabellen.
Mit der Return-Taste kann ich selektierte Tabellenzeilen als Dataset ausgeben lassen.
Diese Daten können dann editiert werden.
Nun möchte ich in dem Dataset, an einer bestimmten Position ein Auswahlmenü verknüpfen, um so den Text des betreffende Item zu ändern.
Leider komme ich alleine nicht weiter und würde mich so auf Eure Hilfe freuen!
Ich habe dazu einen lauffähigen Code anzubieten, damit Ihr Euch vorstellen könnt, wie das mit der Dataset-Ausgabe funktioniert.
Wichtige Zeilenpositionen sind:
162 - 173 = TableItemCompleter
204 - 206 = Versuch Auswahlmenü zu integrieren
Code: Alles auswählen
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# For Python3.x
import sys
import operator  # used for sorting
import random
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QSize, QEvent, QSortFilterProxyModel
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (QMainWindow, QMdiArea, QWidget, QTableView,
    QAbstractItemView, QGridLayout,
    QStyledItemDelegate, QCompleter, QLineEdit, QApplication)
title = 'Backlight management'
header = ['Pos', 'Supplier', 'Artikel', 'Benennung']
table = [['001', 'Meyer', '47110', 'Bratwurst weiss, 125 g / Stück, 50% Schweinefleisch, 50% Rindfleisch'],
    ['002', 'Mueller', '47110', 'Bratwurst weiss, 125 g / Stück, 50% Schweinefleisch, 50% Rindfleisch'],
    ['003', 'Mauser', '47110', 'Bratwurst weiss, 125 g / Stück, 50% Schweinefleisch, 50% Rindfleisch']]
columnWidths = [20, 30, 40, 400]
completer_list = ['Mauser', 'Meyer', 'Mueller']
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("MDI demo")
        self.mdi_area = QMdiArea()
        self.setCentralWidget(self.mdi_area)
        self.mdi_area.tileSubWindows()
        title = 'TEST'
        self.list_model = 'listinlist'
        sub = Table(self, title, table, header, columnWidths)
        self.mdi_area.addSubWindow(sub)
        sub.show()
class Table(QWidget):
    def __init__(self, parent, title, dataList, header, columnWidths):
        QWidget.__init__(self)
        self.parent = parent
        self.title = title
        self.old_data = self.mylist = self.dataList = sorted(dataList)
        self.header = header
        self.columnWidths = columnWidths
        self.mdi_area = parent.mdi_area
        self.setWindowTitle(self.title) 
        self.installEventFilter(self)
        self.view = QTableView()
        self.model = TableModel(self, self.dataList, self.header)
        self.update_table()
        self.headerSize(parent)
        # GridLayout
        grid = QGridLayout() 
        grid.addWidget(self.view, 0, 0)
        self.setLayout(grid) 
    def updateGeometryAsync(self):
        QtCore.QTimer.singleShot(0, self.updateGeometry)
    def headerSize(self, parent):
        """
        Build header- and columnsize
        """
        view = self.view
        model = self.model
        view.setModel(model)
        view.resizeColumnsToContents()
        view.resizeRowsToContents()
        view.setWordWrap(True)
    def update_table(self):
        # ... when a row header label changes and makes the
        # width of the vertical header change too       
        self.model.headerDataChanged.connect(self.updateGeometryAsync)
        self.view.setModel(self.model)
        # enable sorting
        self.view.setSortingEnabled(True)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.old_data_counter = len(self.mylist)
        self.mdi_area.adjustSize()
        index = self.view.model().index(0, 1)
        self.view.setCurrentIndex(index)
    def eventFilter(self, widget, event):
        if event.type() == QtCore.QEvent.KeyPress and widget is self:
            key = event.key()
            if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter):
                DatasetView(self, self.view, self.model)
            return True
        return QWidget.eventFilter(self, widget, event)
class TableModel(QtCore.QAbstractTableModel):
    """
    Build table
    """
    def __init__(self, parent, mylist, header, *args):
        QtCore.QAbstractTableModel.__init__(self, parent, *args)
        self.mylist = mylist
        self.header = header
    def rowCount(self, parent):
        return len(self.mylist)
    def columnCount(self, parent):
        return len(self.mylist[0])
    def data(self, index, role):
        if not index.isValid() or role != QtCore.Qt.DisplayRole:
            return None
        return self.mylist[index.row()][index.column()]
    def headerData(self, col, orientation, role):
        if (orientation == QtCore.Qt.Horizontal
                and role == QtCore.Qt.DisplayRole):
            return self.header[col]
        return None
    def sort(self, col, order):
        """
        Sort table by given column number col
        """
        self.layoutAboutToBeChanged.emit()
        self.mylist = sorted(self.mylist,
            key=operator.itemgetter(col))
        if order == QtCore.Qt.DescendingOrder:
            self.mylist #.reverse()
        self.layoutChanged.emit()
    def output_list(self):
        return self.mylist
class DatasetView(object):
    #def datasetView(self):
    def __init__(self, parent, view, model):
        self.parent = parent
        self.model = model
        self.mdi_area = self.parent.mdi_area
        i = QAbstractItemView.SelectRows
        self.mylist = model.output_list()
        self.index = view.selectedIndexes()[0].row()
        dataset = self.mylist[self.index]
        header = parent.header
        width = 300
        dialog = Dataset(self, dataset, header, width)
        self.new_child_window(dialog)
    def new_child_window(self, dialog):
        # Show dataset window
        sub = self.mdi_area.addSubWindow(dialog).show()
class TableItemCompleter(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        print('#######################')
        print('index', index)
        editor = QLineEdit(parent)
        print('editor', editor)
        print('index.data', index.data(), index.data(Qt.UserRole))
        completion_ls = index.data(Qt.UserRole) # get list
        completer = QCompleter(completion_ls, parent)
        editor.setCompleter(completer)
        print('#######################')
        return editor
class Dataset(QWidget): 
    def __init__(self, parent, dataset, header, columnWidths): 
        super(Dataset, self).__init__()
        self.parent = parent
        self.dataset = dataset
        self.header = header
        self.columnWidths = columnWidths
        self.setObjectName('DATASET')
        self.installEventFilter(self)
        self.setFocusPolicy(Qt.StrongFocus)
        self.view = QTableView(self)
        self.view.clicked.connect(self._item_clicked)
        # GridLayout
        grid = QGridLayout() 
        grid.addWidget(self.view, 0, 0)
        self.setLayout(grid)
        self.model = QStandardItemModel(self)
        # Load dataset
        [self.model.invisibleRootItem().appendRow(
            QStandardItem(column)) for column in self.dataset]
        # 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)
        # set completer for item
        self.view.setItemDelegate(TableItemCompleter(
            self.model.invisibleRootItem().child(1).setData(
            (Qt.UserRole, random.sample(completer_list, 1)))))
    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()
        return QSize(width, height)
    def _item_clicked(self, index):
        # numeric position of dataset
        pos2dataset = index.row()
        # in front of item
        self.item_after = index.sibling(1,0)
        # in front of item
        item_before = index.sibling(-1,0)
def main():
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())
if __name__ == '__main__':
    main()