Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Varying time problems dynamically filling a QTableWidget
Forum Updated to NodeBB v4.3 + New Features

Varying time problems dynamically filling a QTableWidget

Scheduled Pinned Locked Moved C++ Gurus
6 Posts 3 Posters 2.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    resUtQ
    wrote on last edited by
    #1

    Ok Guys I am really puzzled by this. I wrote a small tool for managing components (stuff like resistors, leds etc.). I use the sql stuff from Qt to query a sqlite database. Components are displayed in a QTableWidget according to a selection from "Location" or "Category". The whole selection stuff works, according to the selection a SQL "WHERE" is created (or not if all is to be displayed).

    Everything works fine except that in a very specific case the filling of the QTableWidget takes a considerable amount of time. Please not: It is NOT the sqlquery which is delaying.

    Please excuse my code mess. Here's the function "updateComponentsTable" I use to refresh my QTableWidget. Line 53-68 show the for loop where the time is lost. I added some debug messages to quickly tell the time.

    First the Debug output: First time updateComponentsTable is called is right after startup. The exact same query is triggered manually a few seconds later. You see the difference of filling the table (the for loop). Initially it takes milliseconds. The second time it takes 24 Seconds. However thats the exact same query, the query itself took like no time. And this only happens when the "WHERE" string is empty, even so thats (imho) totally unrelated to the problem.

    This is confusing me, is there some sort of GUI Race condition, is it a system problem regarding the frequent allocating of new QTableItemWidgets? (We're talking of less than 150 Elements) I put breakpoints at almost every location in my code, at least according to the debugger the prgramm is not doing anything besides filling the table. I don't know how to debug this further.

    Regards
    Christoph

    @Start QTime("10:58:47.610")
    whereString done QTime("10:58:47.610")
    where -> ""
    getTableData done QTime("10:58:47.614") # Elements 129
    setup Table done QTime("10:58:47.632")
    fill Table done QTime("10:58:47.638") count 129

    Start QTime("10:58:49.848")
    whereString done QTime("10:58:49.848")
    where -> ""
    getTableData done QTime("10:58:49.851") # Elements 129
    setup Table done QTime("10:58:49.853")
    fill Table done QTime("10:59:14.427") count 129@

    @// updates main components table regarding WHERE string
    void MainWindow::updateComponentsTable(){

    qDebug() << "\n\n\nStart " << QTime::currentTime();
    
    // which columns are to be used?
    QVector<int> use;
    use << 0 << 1 << 2 << 3 << 8 << 10 << 12;
    
    // where string for categories and locations
    QString where;
    whereStringTree("category_id",ui->tw_categories,where);
    whereStringTree("location_id",ui->tw_locations,where);
    
    qDebug() << "whereString done " << QTime::currentTime() ;
    qDebug() << "  where -> " << where ;
    
    ui->te_where->setText(where);
    
    QVector<QVector<QString>* > * data = new QVector<QVector<QString>* >();
    m_db->getTableData("components",where,data);
    
    qDebug() << "getTableData done " << QTime::currentTime() << " # Elements " << data->count() ;
    
    QMap<int, QString> id_name_locations;
    m_db->getKeyValueMap("locations",id_name_locations);
    
    QMap<int, QString> id_name_categories;
    m_db->getKeyValueMap("categories",id_name_categories);
    
    //--
    ui->l_count->setText(QString("# of Components found: %1").arg(data->count()));
    
    ui->tw_components->clearContents();
    ui->tw_components->setRowCount(data->count());
    ui->tw_components->setColumnCount(use.count());
    
    QStringList h = m_db->getColumnNamesComponents("components");
    QStringList h_;
    for(int i = 0; i < use.count(); i++){
        h_.append(h.at(use.at(i)));
    }
    ui->tw_components->setHorizontalHeaderLabels(h_);
    ui->tw_components->verticalHeader()->setVisible(false);
    ui->tw_components->setSelectionBehavior(QAbstractItemView::SelectRows);
    //--
    
    qDebug() << "setup Table done " << QTime::currentTime() ;
    
    int count = 0;
    int rowmax = data->count();
    
    for(int row = 0; row < rowmax; row++){
        ++count;
        QVector<QString> * rowdata = data->at(row);
        for(int col = 0; col < use.count(); col++){
            if(use.at(col) == 10)
                ui->tw_components->setItem(row, col,
                                           new QTableWidgetItem(id_name_locations[rowdata->at(use.at(col)).toInt()]));
            else if(use.at(col) == 12)
                ui->tw_components->setItem(row, col,
                                           new QTableWidgetItem(id_name_categories[rowdata->at(use.at(col)).toInt()]));
            else
                ui->tw_components->setItem(row, col,
                                           new QTableWidgetItem(rowdata->at(use.at(col))));
    
            //qDebug() << "fill Table done " << QTime::currentTime() << " count " <<  count ;
        }
    }
    
    ui->tw_components->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    
    qDebug() << "fill Table done " << QTime::currentTime() << " count " <<  count ;
    

    }@

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      How often does the time increase happen ?

      Out of curiosity, since you have a database, why not make use of QTableView ?

      From a programming point of view:
      @QVector<QVector<QString>* > * data@
      Why these pointers to QString and QVector ?

      You also have multiple memory leaks here since you never delete anything

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • W Offline
        W Offline
        Whatever123
        wrote on last edited by
        #3

        Hi sorry for the delay
        1.
        I am "resUtQ". For some reason i cannot use my account...

        [quote author="SGaist" date="1417822711"]Out of curiosity, since you have a database, why not make use of QTableView ?

        From a programming point of view:
        @QVector<QVector<QString>* > * data@
        Why these pointers to QString and QVector ?

        You also have multiple memory leaks here since you never delete anything[/quote]Totally insensible use of C++. I tend to write C with Classes, not C++ which sometimes leads to nonsense like Vectors of pointers. Anyway it does work, still you are correct pointing out the memory leak. I will fix that ... maybe ;-)

        I found the solution.
        It's totally unrelated to the query, apparantly it comes from whatever happens to the GUI side of QTableWidget when inserting a new element. Looks like inserting to many new Items leads to that kind of problem, I did not investigate further, here is the workaround by (which sounds like a joke) "turning it off an on again" ;-)

        Solution as Pseudocode:
        @QTableWidget::setVisible(false);
        for(...){
        QTableWidget::setItem()
        }
        QTableWidget::setVisible(true);@

        Thanks anyway.
        Christoph

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          If you insert that much items you should rather consider setUpdatesEnable that will avoid the flicker of setVisible

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • W Offline
            W Offline
            Whatever123
            wrote on last edited by
            #5

            It does not flicker for me. But thanks for the Info.

            Anyway I would not recommend my code. Better check out QSqlTableModel and Model/View pattern and the use of delegates. I was not really aware of all that.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Indeed, if you have a database behind that, the QSql* classes are a good choice.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved