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

How to accelerate the selection in the QTableView ?



  • I use the MVC to show a bund of of filenames , and there are opertions of selecting all and dissecting all in the CTableView . The number of files may thousands , so , I write a thread to do these ,like:

    for (int row = 0; row < m_ImgMgr->m_TableModel->rowCount(); row++)
    	{
    
    
    		//QtSleep(5);
    
    		for (int column = 0; column < m_ImgMgr->m_TableModel->columnCount(); column++)
    		{
    
    			//LogLog( QString(" sel 1") ) ;
    			m_ImgMgr->listImages2->selectionModel()->select(m_ImgMgr->listImages2->model()->index(row, column), QItemSelectionModel::Select);
    
    		}
    
    		//LogLog(QString(" sel 2"));
    
    		m_ImgMgr->labelImageIndex->setText(QString::number(row+1) + QString("/") + QString::number(m_ImgMgr->m_TableModel->rowCount()));
    		
    		//LogLog(QString(" sel 3"));
    
    	}
    

    but consuming time is not acceptable . And if the number is very large , the operation seems become more and more slowly by the end of the loop , it can be seen by the count number displayed in the GUI .

    I also tried like below:

    	QItemSelection sel = m_ImgMgr->listImages2->selectionModel()->selection( ) ;
    
    	QModelIndex topleft     = m_ImgMgr->listImages2->model()->index( 0 , 0 ) ;
    	QModelIndex bottonright = m_ImgMgr->listImages2->model()->index(m_ImgMgr->m_TableModel->rowCount(), 3 ) ;
    
    	sel.select( topleft  , bottonright ) ;
    

    no funtional.



  • I can't reproduce the problem. try this minimal example and see if it works for you:

    #include <QTableView>
    #include <QVBoxLayout>
    #include <QStandardItemModel>
    #include <QApplication>
    #include <QPushButton>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QWidget mainWid;
        QAbstractItemModel* model = new QStandardItemModel(&mainWid);
        model->insertColumns(0,4);
        model->insertRows(0,5000);
        for(int rowIter = 0, maxRow = model->rowCount();rowIter<maxRow;++rowIter){
            for(int colIter = 0, maxCol = model->columnCount();colIter<maxCol;++colIter){
                model->setData(model->index(rowIter,colIter),QStringLiteral("%1,%2").arg(rowIter+1).arg(colIter+1));
            }
        }
        QTableView* table = new QTableView(&mainWid);
        table->setModel(model);
        QPushButton* selectAllButton = new QPushButton(QStringLiteral("Select All"),&mainWid);
        QObject::connect(selectAllButton,&QPushButton::clicked,table,[table]()->void{
            const QItemSelection selec(table->model()->index(0,0),table->model()->index(table->model()->rowCount()-1,table->model()->columnCount()-1));
            table->selectionModel()->select(selec,QItemSelectionModel::ClearAndSelect);
        });
        QVBoxLayout* mainLay = new QVBoxLayout(&mainWid);
        mainLay->addWidget(selectAllButton);
        mainLay->addWidget(table);
        mainWid.show();
        return a.exec();
    }
    

    P.S.

    I write a thread to do these

    Don't do GUI operations in secondary threads


  • Lifetime Qt Champion

    How should your second approach work when you don't pass it to the selection model?
    And doing stuff for a model/view in a thread will not work out of the box since the models and views are not threadsafe



  • @VRonin said in How to accelerate the selection in the QTableView ?:

    QTableView* table = new QTableView(&mainWid);

    So great , I am still totally ignorant to MVC .

    Really apreciation.



  • @Christian-Ehrlicher

    thanks for your suggestion.


Log in to reply