Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Custom painting in ListView along many rows?



  • I am porting much of my QtWidgets app to QtQuick. The most custom widget is a QTableView where I left a column empty so I could draw brackets - date-ranges with start+end windows - to relate various rows (see far-left column in screenshot).

    How can I accomplish this in QtQuick? In the QtWidgets version I did the drawing using QPainter in QTableView::paintEvent. I am not tied to the specific look in the example (up for suggestions, actually) but do need to quickly differentiate between the various date ranges depicted in the table.

    FWIW - I didn't have much luck with TableView (seemed buggy - can't remember why) so started using ListView instead with fixed column widths.

    Thanks!

    0_1561794473368_Screen Shot 2019-06-28 at 11.47.30 PM.png


  • Lifetime Qt Champion

    Hi
    Can you use a delegate for that special col?
    https://wiki.qt.io/How_To_Use_QML_ListView#Delegate



  • @mrjj said in Custom painting in ListView along many rows?:

    Hi
    Can you use a delegate for that special row?
    https://wiki.qt.io/How_To_Use_QML_ListView#Delegate

    Correct me if I’m wrong, but a delegate only paints one row. I’m not sure how that makes sense given my example.


  • Lifetime Qt Champion

    @patrickkidd
    Well it paints the rows, so for the Location and Func you draw the pattern and
    for the rest just the data.
    But you are right. I had hoped one could set on a column only like in Widgets.



  • I figured it out. It's pretty funny, I had to start thinking Quick a little more.

    I solved the problem by just adding an Item to the TableView itself that fills the entire column fo the first header, then does the math to determine where the rows are. I return a python dict with the appropriate named values for each shape I want to draw in the column, accessible by model.<whatever>

    TableView {
    
        delegate: 
    
            Item {
                id: buddyItem
                x: 0; y: 0
                width: columnWidth(0)
                height: table.contentHeight
                Repeater {
                    model: table.model.dateBuddies
                    Shape {
                        id: box
                        y: modelData.startRow * util.QML_ITEM_HEIGHT
                        height: (modelData.endRow - modelData.startRow + 1) * util.QML_ITEM_HEIGHT
                        width: parent.width
                        ShapePath {
                            id: bracket
                            startX: box.width
                            startY: 0
                            strokeColor: modelData.color
                            strokeWidth: 1
                            fillColor: 'transparent'
                            PathQuad {
                                x: box.width
                                y: box.height
                                controlX: -box.width + 2
                                controlY: box.height / 2
                            }
                        }
                    }
                }
            }
        ...
    

    This approach is way, way faster than the QTableView/QItemDelegate/QPainter approach because it is only redrawn when the model data changes and not every single bloody paint cycle.

    Pretty sweet!


Log in to reply