How to use a validator with QTableWidgetItem?
Asked Answered
W

4

8

Assuming I have a QTableWidgetItem item and I just wanna validate data that users enter. Example, users only enter a number into that item otherwise the program will show a warning dialog.

I also search on that document page but I didn’t find similar function with setValidator() function.

How can I use a validator for that QTableWidgetItem item?

Wakashan answered 19/8, 2013 at 8:45 Comment(0)
A
11

Assuming what you really want is to have QValidate-able cells, you could populate the cell with a QLineEdit instance instead. Here's an example that uses QDoubleValidator, but any QValidator will work:

QLineEdit *edit = new QLineEdit(ui->myTable);
edit->setValidator(new QDoubleValidator(edit));
ui->myTable->setCellWidget(row, col, edit);

By default, QLineEdit will fill the cell and is drawn with a frame. To preserve the appearance of the table, you can turn the frame off by calling the following function a priori:

QLineEdit::setFrame(false);

One annoying thing about this solution is that you'll have to call

QWidget* QTableWidget::cellWidget(row, col) const

to subsequently access the QLineEdit instance in each cell, which means you'll have to cast the pointer to QLineEdit* also. (See qobject_cast()). It's a bit verbose but workable.

Ancestor answered 25/2, 2014 at 10:55 Comment(1)
Nice workaround! Although the lineedit first cell (0, 0) is a bit misplaced. Every other cell looks great but the very first one seems to be too high, too left, too wide and too tall.Szechwan
P
4

I can think of two different ways you can handle this. There may be other solutions as well.

You could subclass the QTableWidgetItem and reimplement the setData function. If you pick up an invalid value, you can emit an error message.

You could subclass QStyledItemDelegate and either add a QValidator to the editor QWidget by reimplementing createEditor or reimplement the setModelData and examine the user input there. Once again, you can emit an error message if there's invalid data.

Check the documentation of each to see which would be more appropriate for your project.

QTableWidgetItem

QStyledItemDelegate

Pancreas answered 19/8, 2013 at 8:57 Comment(0)
S
1

I use this solution where you have a QLineEdit in each cell. the validator is for scientific numbers (e.g. 2e-17)

for(int trow=0; trow <= 2; trow++ )
{
    for(int tcolumn=0; tcolumn <= 3; tcolumn++ )
    {
        QLineEdit * tableline = new QLineEdit;
        tableline->setValidator( new QDoubleValidator(0, 100, 2, this) );
        ui->tableWidget->setCellWidget ( trow, tcolumn,  tableline);
    }
Semele answered 28/9, 2016 at 12:16 Comment(0)
T
1

There's easy way to achieve this.

Just use one of the signals of QTableWidget - cellChanged(int,int);

QObject::connect(m_pTableWidget, SIGNAL(cellChanged(int,int)),
                         this, SLOT(OnTableWidgetCellChanged(int,int)));

Inside slot function (OnTableWidgetCellChanged(int row,int column)), use a switch case with column to validate each column seperately.

Get the input text from user of that particular column, and store as QString. Now convert that QString to int by passing the bool variable and check the status of bool variable. If its false, then user entered is not a valid number. example is shown as below :

bool bRetValue = false;
QString strValue = m_pTableWidget->item(row, VALUE_INDEX)->text();

int nValue = strValue.toInt(&bRetValue);
if(bRetValue == false)
{
  // show dialog to user to enter only numbers
}

If you want to convert to double or other type, simply convert the value to qvariant and can follow same procedure.

QVariant qvarValue(strValue);
double dVal = qvarValue.toDouble(&bRetValue);
if(bRetValue == false)
{
  // show dialog to user to enter only numbers
}

If you want to be more specific you can use QRegExp or QRegularExpression(Qt5)

QRegularExpression regexp("enter regx here",
                              QRegularExpression::CaseInsensitiveOption);
QRegularExpressionMatch regxmatch = regexp.match(strValue);
if (regxmatch.hasMatch())
{
    // your functionality
}
else
{
    // show dialog to user to enter only numbers
}
Triptych answered 19/7, 2020 at 17:34 Comment(1)
this is helpful but when the user input is wrong you can not restore item text to the previous state you just have to put default valueSession

© 2022 - 2024 — McMap. All rights reserved.