Hallo __deets__,
Deine Vermutung trifft voll ins Schwarze.
beschreibe mal kurz mein Vorhaben.
In der Tabelle kann ich mit den Tasten Up und Down, Tabellenzeilen ansteuern, was gut funktioniert. Mit der Maus, habe ich eine vorübergehende Lösung, die ich gerne ersetzen möchte.
Ich poste hier mal den abgespeckten Code, der lauffähig ist.
Hier sind die Buttons Up und Down nicht integriert, um den Code nicht größer zu machen.
Hoffe, Du kannst dadurch das Problem eingrenzen.
Code: Alles auswählen
import sys
from PyQt5.QtCore import (
Qt,
QEvent,
QAbstractTableModel,
)
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QTableView,
QAbstractItemView,
QSizePolicy,
QGridLayout,
QMdiArea,
QWidget,
)
from PyQt5.QtGui import (
QStandardItem,
QStandardItemModel,
)
class TableWindow(QMainWindow):
def __init__(self, filename, header, data):
super(TableWindow, self).__init__()
self.installEventFilter(self)
self.mdi = QMdiArea()
self.mdi.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.mdi.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setCentralWidget(self.mdi)
self.setGeometry(0, 0, 500, 500)
self.setWindowTitle(filename)
obj = Table(filename, header, data)
self.printObject = obj
self.mdi.addSubWindow(obj)
self.show()
self.mdi.activeSubWindow().showMaximized()
class Table(QTableView):
def __init__(self, filename, header, data):
QWidget.__init__(self)
self.old_data = self.mylist = self.data = sorted(data)
self.header = header
if not self.header:
self.header = ['col_{}'.format(i)
for i in range(len(self.data[0]))]
self.rowCounter = len(self.data) - 1
self.index = self.rowIndex = 0
self.viewport().installEventFilter(self)
self.view = QTableView(self)
grid = QGridLayout()
grid.addWidget(self.view, 0, 0)
self.setLayout(grid)
self.model = TableModel(self.data, self.header)
self.update_table()
self.headerSize()
def updateGeometryAsync(self):
QTimer.singleShot(0, self.updateGeometry)
def headerSize(self):
"""
Build header- and columnsize
"""
self.view.setModel(self.model)
self.view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.view.resizeColumnsToContents()
self.view.resizeRowsToContents()
self.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.view.setSelectionMode(QAbstractItemView.SingleSelection)
self.view.setFocus()
self.view.selectRow(self.rowIndex)
self.adjustSize()
def controlBackNext(self):
print('rowIndex: ',self.index)
def eventFilter(self, widget, event):
try:
if self.view.selectedIndexes()[0].row() != self.index:
print('eventTyp, QEvent.MouseButtonPress: ',
event.type(), QEvent.MouseButtonPress)
self.index = self.view.selectedIndexes()[0].row()
self.controlBackNext()
except (AttributeError, IndexError):
pass
return QWidget.eventFilter(self, widget, event)
class TableModel(QAbstractTableModel):
def __init__(self, mylist, header, *args):
QAbstractTableModel.__init__(self, *args)
self.mylist = mylist
self.header = header
def rowCount(self, widget):
return len(self.mylist)
def columnCount(self, widget):
return len(self.mylist[0])
def data(self, index, role):
if not index.isValid() or role != Qt.DisplayRole:
return None
return self.mylist[index.row()][index.column()]
def headerData(self, col, orientation, role):
if (orientation == Qt.Horizontal
and role == Qt.DisplayRole):
return self.header[col]
elif (orientation == Qt.Vertical
and role == Qt.DisplayRole):
return col
return None
def output_list(self):
return self.mylist
def main():
filename = 'Testtabelle'
header = False
data = [['fritz', 'müller', 'fritz', 'müller', 'müller', 'müller'],
['fritz', 'müller', 'fritz', 'müller', 'müller', 'müller'],
['fritz', 'müller', 'fritz', 'müller', 'müller', 'müller'],
['fritz', 'müller', 'fritz', 'müller', 'müller', 'müller'],
]
App = QApplication(sys.argv)
ex = TableWindow(filename, header, data)
sys.exit(App.exec())
if __name__ == '__main__':
main()