简体   繁体   中英

QTableWidget not displaying rows

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?

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.

屏幕截图

// 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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM