3

I have created a QTableWidget in which I've used setCellWidget(QWidget*). I've set QLineEdit in the cell widget. I've also created a delete button and clicking that button sends a signal to the function deleteRow. I've also used a function currentRow() to get the current row, but it returns -1 because of the QLineEdit. The code snippet is below.

void createTable() {
    m_table = new QTableWidget(QDialog); //member variable
    for (int i = 0; i < 3; i++)
    {
        QLineEdit *lineEdit = new QLineEdit(m_table);
        m_table->setCellWidget(i, 0, lineEdit);
    }
    QPushButton *deleteBut = new QPushButton(QDiaolg);
    connect(deleteBut, SIGNAL(clicked()), QDialog, SLOT(editRow()));
}

editRow() {
    int row = m_table->currentRow(); // This gives -1
    m_table->remove(row);
}

In above scenario I click in the QLineEdit and then click on the button delete. Please help me out with a solution.

Ilya
  • 4,583
  • 4
  • 26
  • 51
njporwal
  • 111
  • 2
  • 4
  • 9

3 Answers3

3

Just tried it here, it seems that currentRow of the table returns -1 when clicking the button right after program start, and when first selecting a cell, then selecting the QLineEdit and then clicking the button, the correct row is returned.

I would do the following as a workaround: Save the row number in the QLineEdit, e.g. by using QObject::setProperty:

 QLineEdit *lineEdit = new QLineEdit(m_table);
 lineEdit->setProperty("row", i);
 m_table->setCellWidget(i, 0, lineEdit);

Then, in the editRow handler, retrieve the property by asking the QTableWidget for its focused child:

int row = m_table->currentRow();
if (row == -1) {
  if (QWidget* focused = m_table->focusWidget()) {
    row = focused->property("row").toInt();
  }
}
Karsten Koop
  • 2,475
  • 1
  • 18
  • 23
0

The accepted solution, as is, would not work if rows might get deleted while the program runs. Thus the approach would require to update all the properties. Can be done, if this is a rare operation.

I got away with an iteration approach:

for(unsigned int i = 0; i < table->rowCount(); ++i)
{
    if(table->cellWidget(i, relevantColumn) == QObject::sender())
    {
        return i;
    }
}
return -1;

Quick, dirty, but worked, and in my case more suitable, as rows got deleted often or changed their positions, only buttons in the widget were connected to the slot and the slot was never called directly. If these conditions are not met, further checks might get necessary
(if(QObject::sender()) { /* */ }, ...).

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
0

Karsten's answer will work correctly only if QLineEdit's property is recalculated each time a row is deleted, which might be a lot of work. And Aconcagua's answer works only if the method is invoked via signal/slot mechanism. In my solution, I just calculate the position of the QlineEdit which has focus (assuming all table items were set with setCellWidget):

int getCurrentRow() {

  for (int i=0; i<myTable->rowCount(); i++)
    for (int j=0; j<myTable->columnCount(); j++) {
        if (myTable->cellWidget(i,j) == myTable->focusWidget()) {
             return i;
        }
    }

  return -1;
}
Maximko
  • 627
  • 8
  • 20