I have table widget, where one of the columns needs to have text autocopletion.
Each time the user request a new row I run this code for that column:
else if (i == COLUMN_DESCRIPICION){
QLineEdit *le = new QLineEdit(this);
QStringList list = dbManager.getProductListStringsOnly();
QCompleter *completer = new QCompleter(list,le);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
le->setCompleter(completer);
ui->twReceiptItems->setCellWidget(rowindex,i,le);
}
So far so good. Now the user might need to input a new item to the system. If he does, then that Item also needs to be in the list of EXISTING rows. So to update the QCompleter word list I run this:
void MainView::updateProductList(){
if (ui->twReceiptItems->rowCount() == 0) return;
QStringList list = dbManager.getProductListStringsOnly();
for (qint32 i = 0; i < ui->twReceiptItems->rowCount(); i++){
qDebug() << 1;
QLineEdit *le = static_cast<QLineEdit*>(ui->twReceiptItems->cellWidget(i,COLUMN_DESCRIPICION));
qDebug() << 2 << (le == nullptr);
QCompleter *completer = le->completer();
qDebug() << 3 << (completer == nullptr);
QStringListModel *model = static_cast<QStringListModel*>(completer->model());
qDebug() << 4 << (model == nullptr);
if (model == nullptr) model = new QStringListModel();
qDebug() << 5 << (model == nullptr);
model->setStringList(list);
qDebug() << 6;
completer->setModel(model);
qDebug() << 7;
le->setCompleter(completer);
qDebug() << 8;
}
}
The program crashes between qDebug line 6 and 7. But I can't figure out what I'm doing wrong.
You're trying to replace the completer model using a pointer to its current one. When you call setModel
a delete on the current object is called, and it happens to be the very same object you're trying to set as the new one.
Here you set a pointer to the current model:
QStringListModel *model = static_cast<QStringListModel*>(completer->model());
here you set it back:
completer->setModel(model);
Just use a new one, instead, ie
completer->setModel(new QStringListModel(list));
or, even better
le.completer()->setModel(new QStringListModel(list));
Just a footnote: don't use static_cast
for up-casting. C++ has a specific cast for that, dynamic_cast
, and Qt even has qobject_cast
for QObject derivatives.
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.