-1

I have to display a list of item with a QTableWidget. I am inserting such items dynamically at runtime.

The problem is that the QTableWidget control is not displaying any rows. I have verified with the debugger that the items do get inserted, but for some reason the widget does not get refreshed / repainted.

I have extensively searched the web and tried the proposed solutions for similar cases, but without success.

Please find below the relevant code:

QTableWidget.ui

    <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>QDialogClassName</class>
 <widget class="QDialog" name="QDialogClassName">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>587</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="windowTitle">
   <string>QDialogClassName</string>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>40</y>
     <width>781</width>
     <height>541</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QLabel" name="introductionLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="autoFillBackground">
       <bool>false</bool>
      </property>
      <property name="text">
       <string>Label</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
      <property name="sizeType">
       <enum>QSizePolicy::Fixed</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>20</height>
       </size>
      </property>
     </spacer>
    </item>
    <item>


   <widget class="QTableView" name="tableView">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>30</y>
      <width>551</width>
      <height>271</height>
     </rect>
    </property>

    <property name="sortingEnabled">
       <bool>true</bool>
    </property>
    <attribute name="horizontalHeaderVisible">
       <bool>true</bool>
    </attribute>
    <attribute name="horizontalHeaderStretchLastSection">
       <bool>true</bool>
    </attribute>    
   </widget>




    </item>
    <item>
     <widget class="QProgressBar" name="progressBar">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="value">
       <number>24</number>
      </property>
     </widget>
    </item>
    <item>
     <layout class="QHBoxLayout" name="buttonsHorizontalLayout">
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="previousBackButton">
        <property name="text">
         <string>Previous...</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="nextButton">
        <property name="text">
         <string>Next...</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

ui_QTableWidget.h

    tableWidget = new QTableWidget(verticalLayoutWidget);
    tableWidget->setObjectName(QStringLiteral("tableWidget"));
    tableWidget->setShowGrid(true);
    tableWidget->setColumnCount(N_COLUMNS);
    tableWidgetHeader << "Header1" << "Header2";
    tableWidget->setHorizontalHeaderLabels(tableWidgetHeader);
    tableWidget->setRowCount(0);
    tableWidget->verticalHeader()->setVisible(true);
    tableWidget->verticalHeader()->show();

    verticalLayout->addWidget(tableWidget);

QTableWidget.cpp

int row_count;
QTableWidgetItem *itab;
row_count = ui->tableWidget->rowCount();
ui->tableWidget->insertRow(row_count);
// as an alternative to the above line of code I have also tried ui->tableWidget->->setRowCount(row_count);


itab = new QTableWidgetItem;
itab->setText("Cell1");
ui->tableWidget->setItem(row_count, 0, itab);
ui->tableWidget->item(row_count, 0)->setBackground(Qt::red);

itab = new QTableWidgetItem;
itab->setText("Cell2");
ui->tableWidget->setItem(row_count, 1, itab);
ui->tableWidget->item(row_count,1)->setBackground(Qt::green);

/*Each of the following lines is an attempted solution. Other proposed solutions include emiting rowCountChanged and similar protected signals. */
    //ui->tableWidget->update();
    //ui->tableWidget->show();
    //ui->tableWidget->viewport()->update();
    //ui->tableWidget->viewport()->show();

What am I doing wrong? How can I fix this?

geraldCelente
  • 1,005
  • 2
  • 16
  • 36

1 Answers1

3

It seems that you are doing everything almost right. There are two problems:

  1. When you're inserting items into a table widget that can be potentially sorted, each row item change can resort the view and end up changing the row indices. After you set the item1's text, the row it's in will not be the row you inserted the empty row into. You must get the item's row after each text change.

  2. Your UI file is slightly broken because there's no top-level layout, but that doesn't affect the functionality of the view per se.

The following test case demonstrates that it all works. Some other code that you're not showing here is broken.

  1. Does your row insertion code ever run? Set a breakpoint there and see if it triggers.

  2. Do you have other views? Perhaps overlapping ones? Are you sure that you're adding rows to the view that you're looking at?

  3. Make sure that you see the headers of the table widget - if you don't, then your entire table widget is not visible, and your problem has nothing to do with any rows you are inserting.

  4. Are you blocking the event loop after row insertion, never giving the widget a chance to repaint? Is the application responsive after rows are added?

These are really debugging basics, but you never indicated in the question that you've checked those.

screenshot

// https://github.com/KubaO/stackoverflown/tree/master/questions/tablewidget-32403753
#include <QtWidgets>

int main(int argc, char ** argv) {
   QApplication app{argc, argv};

   QWidget w;
   QVBoxLayout layout { &w };

   QTableWidget tw;
   tw.setShowGrid(true);
   tw.setColumnCount(2);
   auto header = QStringList() << "Header1" << "Header2";
   tw.setHorizontalHeaderLabels(header);
   tw.setSortingEnabled(true);

   QPushButton button { "Add Row" };
   QObject::connect(&button, &QPushButton::clicked, &tw, [&tw]{
      auto row = tw.rowCount();
      tw.insertRow(row);

      auto item1 = new QTableWidgetItem { "Cell1" };
      item1->setBackground(Qt::red);
      tw.setItem(row, 0, item1);
      row = item1->row(); // Needed to support sorted tables.

      auto item2 = new QTableWidgetItem { "Cell2" };
      item2->setBackground(Qt::green);
      tw.setItem(row, 1, item2);
   });

   layout.addWidget(&tw);
   layout.addWidget(&button);
   w.show();
   return app.exec();
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thanks. I can see the headers in my implementation, but I can't see the any rows inserted. That's very strange! – geraldCelente Sep 04 '15 at 18:34
  • @geraldCelente So, you are simply not showing enough code to figure out what's wrong :( – Kuba hasn't forgotten Monica Sep 04 '15 at 18:35
  • I have included all the code relevant to the QTableView control. What else can I do? – geraldCelente Sep 04 '15 at 18:40
  • @geraldCelente I've shown you that your code works. Obviously some other code **is relevant** (perhaps Qt's own code!) even if you think that it isn't. I mean, come on, you have firm experimental proof that your code isn't sufficiently relevant in isolation. I've tested this under Qt 5.4.2, perhaps the version you're using has a bug - but you didn't tell us what version you're using. It's on you to minimize your code step-by-step, eventually arriving at the code I've shown above. At some step you will notice the error go away. – Kuba hasn't forgotten Monica Sep 04 '15 at 18:42
  • I understnad that. My comment was just voicing my thoughts about how to proceed in troubleshooting this issue, I was I kind of "thinking aloud". – geraldCelente Sep 04 '15 at 18:48
  • @geraldCelente I wonder if you're getting yourself into a mess of some sort because you've named your own class `QTableWidget`... That's a bad idea. But, alas, that's only a guess since you've *not* shown enough... Note that if all you wish to show is a lone widget, you don't need any `.ui` files for it. Just show it in isolation, as a top-level widget (a window). – Kuba hasn't forgotten Monica Sep 04 '15 at 18:51
  • The use of QTableWidget is just to make the code as self-explanatory as possible. Anyway I nave now included the entire .ui file. Thanks for your support. I really appreciate it. – geraldCelente Sep 04 '15 at 19:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88841/discussion-between-geraldcelente-and-kuba-ober). – geraldCelente Sep 04 '15 at 20:26