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

Determining the last currently visible QTableWidgetItem



  • Hi :-)

    I need to know the visible row number of QTableWidgetItems. Which is not the row(), as the first visible row is not necessarily row 0, and probably, there are hidden rows, which I need to skip when counting. I do this vis the following function:

    int RegistrationPage::visibleRow(const QTableWidgetItem *item) const
    {
        const auto *firstItem = m_playersList->itemAt(0, 0);
        if (firstItem == nullptr) {
            return -1;
        }
    
        const int firstRow = firstItem->row();
        const int targetRow = item->row();
    
        int visibleRow = 0;
        for (int row = firstRow; row < m_playersList->rowCount(); row++) {
            if (m_playersList->item(row, 0)->row() == targetRow) {
                return visibleRow;
            }
            visibleRow += isRowVisible(row);
        }
    
        return -1;
    }
    

    It iterates, beginning from the first visible row, over all following ones. But this wouldn't be necessary, as this also processes items that aren't inside the current viewport of the QTableWidget, I would only have to check up to the last visible item.

    Now, the question is: How can I determine the last visible item? I can't use itemAt() using the widget's height, as the height isn't the height of the viewport. Maybe I missed something in the docs, but I didn't find a function returning the geometry of the viewport. Also, I would like to get the last item that is completely visible at the bottom …

    Any hints? Thanks for all help in advace :-)

    Cheers, Tobias





  • @Pl45m4 Thanks for the hint! This one does the trick:

    int RegistrationPage::visibleRow(const QTableWidgetItem *item) const
    {
        const auto *firstItem = m_playersList->itemAt(0, 0);
        if (firstItem == nullptr) {
            return -1;
        }
    
        const int targetRow = item->row();
        const int firstRow = firstItem->row();
    
        int lastRow = m_playersList->rowCount();
        const int viewportHeight = m_playersList->viewport()->height();
        const auto *lastItem = m_playersList->itemAt(0, viewportHeight - 1);
        if (lastItem != nullptr) {
            const bool completelyVisible = m_playersList->visualItemRect(lastItem).bottomLeft().y()
                                           <= viewportHeight;
            lastRow = lastItem->row() + completelyVisible;
        }
    
        int visibleRow = 0;
        for (int row = firstRow; row < lastRow; row++) {
            if (m_playersList->item(row, 0)->row() == targetRow) {
                return visibleRow;
            }
            visibleRow += isRowVisible(row);
        }
    
        return -1;
    }

Log in to reply