QStyledItemDelegate crashes my application when I print something on console on paint event

14 views Asked by At

Main Question:

Is there a known threading problem when trying to print something inside a paint event of a QStyledItemDelegate?

Script Files:

style.css:

QTableWidget {
    border: 1px solid #ddd;
}

QTableWidget::item {
    background-color: white;
}

QTableWidget::item:alternate {
    background-color: #f1f1f1;
}

QTableView::item:selected, QTableView::item:alternate:selected {
    background-color: #92b7d1;
}

QHeaderView::section {
    background-color: lightgray;
}

QHeaderView::section:hover {
    background-color: silver;
}

delegate.py:

from PySide2.QtWidgets import QStyledItemDelegate

class TableWidgetDelegate (QStyledItemDelegate):
    def __init__ (self, table):
        QStyledItemDelegate.__init__(self)
        self.table = table

    def paint (self, painter, option, index):
        QStyledItemDelegate.paint(self, painter, option, index)
        print ('Something')

tablewidget.py

from PySide2.QtWidgets import QTableWidget, QTableWidgetItem, QHeaderView, QAbstractItemView
from PySide2.QtCore import Qt
from PySide2.QtGui import QColor
from delegate import TableWidgetDelegate

class TableWidget (QTableWidget):
    def __init__ (self, header=None):
        QTableWidget.__init__(self)
        self.delegate = TableWidgetDelegate(self)
        self.setItemDelegate(self.delegate)

        self.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.setDragDropMode(QAbstractItemView.NoDragDrop)
        self.setFocusPolicy(Qt.NoFocus)
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setAlternatingRowColors(True)
        self.setShowGrid(False)

        tv = self.verticalHeader()
        tv.setVisible(False)
        tv.setSectionsClickable(False)
        tv.setSectionResizeMode(QHeaderView.Fixed)
        tv.setDefaultAlignment(Qt.AlignHCenter)
        
        th = self.horizontalHeader()
        th.setHighlightSections(False)
        th.setStretchLastSection(True)
        th.setSectionResizeMode(QHeaderView.Stretch)

        self.header = None
        self.setHeaders(header)

    def setHeaders (self, header):
        self.setColumnCount(len(header))

        col = 0
        for h in header:
            item = QTableWidgetItem(h)
            item.setTextColor(QColor('black'))
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            self.setHorizontalHeaderItem(col, item)
            col += 1

        self.header = header

    def getColor (self, color):
        if (isinstance(color, QColor)):
            return QColor
        else:
            if (type(color) is str):
                return QColor(color)
            elif (type(color) is tuple):
                channels = len(color)
                if (channels == 3):
                    return QColor(color[0], color[1], color[2], 255)
                elif (channels == 4):
                    return QColor(color[0], color[1], color[2], color[3])
            else:
                return QColor('black')

    def setCellData (self, r, c, value):
        item = self.item(r, c)
        if (item is None):
            item = QTableWidgetItem()
            self.setItem(r, c, item)

        item.setText(str(value))

    def insert (self, index, data):
        nrows = self.rowCount()
        ncols = self.columnCount()

        if (index < 0):
            index += (nrows + 1)

        self.insertRow(index)

        columns = range(ncols)
        for c in columns:
            self.setCellData(index, c, data[c])

main.py

from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from tablewidget import TableWidget

class Scene (QWidget):
    def __init__ (self, win):
        QWidget.__init__(self)
        layout = QVBoxLayout()
        self.window = win
        self.setLayout(layout)

        self.table = TableWidget(['Name', 'Race', 'Class', 'Level'])
        self.table.insert(-1, ['Albert', 'Human', 'Wizard', '3'])
        self.table.insert(-1, ['Dain', 'Dwarf', 'Warrior', '5'])
        self.table.insert(-1, ['Lya', 'Elf', 'Thief', '2'])
        self.table.insert(-1, ['Francis', 'Human', 'Ranger', '4'])

        layout.addWidget(self.table)
        self.window.setWindowTitle('From Scene Widget')

class MainWindow (QMainWindow):
    def __init__ (self, app):
        QMainWindow.__init__(self)
        self.app = app

        # Setting CSS
        try:
            file = open('style.css', 'rt')
        except:
            print ('Failed to load css')
        else:
            data = file.read()
            file.close()

            self.app.setStyleSheet(data)

        # Setting Current Scene
        self.scene = Scene(self)
        self.setCentralWidget(self.scene)

def main ():
    app = QApplication()
    win = MainWindow(app)
    win.show()

    app.exec_()

if __name__ == '__main__':
    main()

Running the Application:

When I type python main.py into my cmd console, this is what shows up: enter image description here

Until here, it's all fine.

However, if you randomly select lines on the console and put the it in front of the Main Window, for some reason, after a few seconds of randomly selecting those lines with the mouse, the application will stop responding. enter image description here

Then, when you finally click enter on the console, nothing shows up. No log, no error messages, no nothing. I believe this is some kind of segmentation fault from the looks of it.

Additional Notes:

I am using Windows 10, Python 3.10, and PySide2.

I also have tried using the faulthandler module to try to get the segmentation fault error, but nothing shows up on my console. It's a silent crash.

Does anyone here knows why it happens? Or maybe it's my own fault, maybe I forgot something? I'm really just starting using QStyledItemDelegates, that's why I'm asking it.

0

There are 0 answers