Skip to content Skip to sidebar Skip to footer

QTableView Doesn't Send Expected FocusIn / FocusOut Events To EventFilter

I have a QTableWidget with floats or complex entries that need a lot of horizontal space. Displaying the values with reduced number of digits via string formatting works fine, but

Solution 1:

You're going about this in completely the wrong way. These kinds of use-cases are already catered for by the existing APIs, so there are several solutions available that are much simpler than what you currently have.

Probably the simplest of all would be to use a QStyledItemDelegate and reimplement its dispalyText method. This will allow you to store the full values in the table, but format them differently for display. When editing, the full value will always be shown (as a string):

from PyQt4.QtGui import (QApplication, QWidget, QTableWidget, QTableWidgetItem,
                         QLabel, QVBoxLayout,QStyledItemDelegate)
import PyQt4.QtCore as QtCore
from PyQt4.QtCore import QEvent
from numpy.random import randn

class ItemDelegate(QStyledItemDelegate):
    def displayText(self, text, locale):
        return "{:.3g}".format(float(text))

class EventTable (QWidget):
    def __init__(self, parent = None):
        super(EventTable, self).__init__(parent)
        self.myTable = QTableWidget(self)
        self.myTable.setItemDelegate(ItemDelegate(self))
        myQVBoxLayout = QVBoxLayout()
        myQVBoxLayout.addWidget(self.myTable)
        self.setLayout(myQVBoxLayout)
        self.rows = 3; self.columns = 4 # table + data dimensions
        self.data = randn(self.rows, self.columns) # initial data
        self._update_table() # create table

    def _update_table(self):
        self.myTable.setRowCount(self.rows)
        self.myTable.setColumnCount(self.columns)
        for col in range(self.columns):
            for row in range(self.rows):
                item = QTableWidgetItem(str(self.data[row][col]))
                self.myTable.setItem(row, col, item)
        self.myTable.resizeColumnsToContents()
        self.myTable.resizeRowsToContents()

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    mainw = EventTable()
    app.setActiveWindow(mainw)
    mainw.show()
    sys.exit(app.exec_())

NB: it's tempting to use item roles to solve this issue. However, both QTableWidgetItem and QStandardItem treat the DisplayRole and EditRole as one role, which means it would be necessary to reimplement their data and setData methods to get the required functionality.


Post a Comment for "QTableView Doesn't Send Expected FocusIn / FocusOut Events To EventFilter"