Unsolved Assigning ItemDelegates to different columns in a view
-
Code is correct but the two suggestions about removing the parent to the delegate are wrong.
from http://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegateForColumn
Any existing column delegate for column will be removed, but not deleted. QAbstractItemView does not take ownership of delegate.
So leave the this in the parent or you'll leak memory
If I use only one of the column assignments the program works. If I use both, the program stops working.
Could you specify "stop working" better?
-
@VRonin
It crashes and gives a message saying unexpectedly stopped. -
Could you post your stacktrace?
-
@VRonin
Yes.
1 myDelegate::createEditor mydelegate.cpp 16 0x41c31f
2 QAbstractItemViewPrivate::editor qabstractitemview.cpp 4199 0x14f94af1
3 QAbstractItemViewPrivate::openEditor qabstractitemview.cpp 4384 0x14f95895
4 QAbstractItemView::edit qabstractitemview.cpp 2676 0x14f8fa8e
5 QAbstractItemView::edit qabstractitemview.cpp 1201 0x14f8acf5
6 QAbstractItemView::closeEditor qabstractitemview.cpp 2852 0x14f904de
7 QAbstractItemView::qt_static_metacall moc_qabstractitemview.cpp 421 0x14f964de
8 QMetaObject::activate qobject.cpp 3740 0x1cb5782
9 QMetaObject::activate qobject.cpp 3602 0x1cb50a2
10 QAbstractItemDelegate::closeEditor moc_qabstractitemdelegate.cpp 204 0x14fcec46
11 QAbstractItemDelegatePrivate::editorEventFilter qabstractitemdelegate.cpp 477 0x14fcdf28
12 QStyledItemDelegate::eventFilter qstyleditemdelegate.cpp 583 0x14ff872d
13 QCoreApplicationPrivate::sendThroughObjectEventFilters qcoreapplication.cpp 1099 0x1c8ca0e
14 QApplicationPrivate::notify_helper qapplication.cpp 3795 0x14d2fb50
15 QApplication::notify qapplication.cpp 3181 0x14d2d24c
16 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x1c8c6e7
17 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0x150ac865
18 QWidgetWindow::handleKeyEvent qwidgetwindow.cpp 656 0x14d7fe17
19 QWidgetWindow::event qwidgetwindow.cpp 232 0x14d7e741
20 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x14d2fb70
21 QApplication::notify qapplication.cpp 3159 0x14d2d143
22 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x1c8c6e7
23 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0x8f380ad
24 QGuiApplicationPrivate::processKeyEvent qguiapplication.cpp 2016 0x8c1c0ac
25 QGuiApplicationPrivate::processWindowSystemEvent qguiapplication.cpp 1693 0x8c1adc8
26 QWindowSystemInterface::sendWindowSystemEvents qwindowsysteminterface.cpp 659 0x8c0cee2
27 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 82 0x1f60569d
28 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 qeventdispatcher_win.cpp 443 0x1cd8f6a
29 USER32!SetManipulationInputTarget 0x7466d2b3
30 USER32!DispatchMessageW 0x7464e88a
31 USER32!DispatchMessageW 0x7464e1e4
32 USER32!DispatchMessageW 0x7464dfa0
33 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 844 0x1cda4f6
34 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x1f605659
35 QEventLoop::processEvents qeventloop.cpp 134 0x1c8a364
36 QEventLoop::exec qeventloop.cpp 212 0x1c8a614
37 QDialog::exec qdialog.cpp 552 0x14f3adfd
38 MainWindow::on_actionFix_Friend_in_DB_triggered mainwindow.cpp 211 0x408e67
39 MainWindow::qt_static_metacall moc_mainwindow.cpp 85 0x424813
40 MainWindow::qt_metacall moc_mainwindow.cpp 117 0x424906
41 QMetaObject::metacall qmetaobject.cpp 301 0x1c91322
42 QMetaObject::activate qobject.cpp 3755 0x1cb582d
43 QMetaObject::activate qobject.cpp 3602 0x1cb50a2
44 QAction::triggered moc_qaction.cpp 369 0x14d24983
45 QAction::activate qaction.cpp 1170 0x14d23c32
46 QAction::event qaction.cpp 1098 0x14d23a14
47 QApplicationPrivate::notify_helper qapplication.cpp 3799 0x14d2fb70
48 QApplication::notify qapplication.cpp 3159 0x14d2d143
49 QCoreApplication::notifyInternal2 qcoreapplication.cpp 988 0x1c8c6e7
50 QCoreApplication::sendEvent qcoreapplication.h 231 0x8f38105
51 QShortcutMap::dispatchEvent qshortcutmap.cpp 674 0x8c4763b
52 QShortcutMap::tryShortcut qshortcutmap.cpp 351 0x8c46906
53 QWindowSystemInterface::handleShortcutEvent qwindowsysteminterface.cpp 235 0x8c0b8f6
54 QGuiApplicationPrivate::processKeyEvent qguiapplication.cpp 2002 0x8c1bfc8
55 QGuiApplicationPrivate::processWindowSystemEvent qguiapplication.cpp 1693 0x8c1adc8
56 QWindowSystemInterface::sendWindowSystemEvents qwindowsysteminterface.cpp 659 0x8c0cee2
57 QWindowsGuiEventDispatcher::sendPostedEvents qwindowsguieventdispatcher.cpp 82 0x1f60569d
58 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 qeventdispatcher_win.cpp 443 0x1cd8f6a
59 USER32!SetManipulationInputTarget 0x7466d2b3
60 USER32!DispatchMessageW 0x7464e88a
61 USER32!DispatchMessageW 0x7464e1e4
62 USER32!DispatchMessageW 0x7464dfa0
63 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 844 0x1cda4f6
64 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x1f605659
65 QEventLoop::processEvents qeventloop.cpp 134 0x1c8a364
66 QEventLoop::exec qeventloop.cpp 212 0x1c8a614
67 QCoreApplication::exec qcoreapplication.cpp 1261 0x1c8cd69
68 QGuiApplication::exec qguiapplication.cpp 1633 0x8c1ac2c
69 QApplication::exec qapplication.cpp 2975 0x14d2cc0b
70 main main.cpp 14 0x403964 -
@gabor53 So your
mydelegate
class is crashing, can we see the code for that? -
in particular myDelegate::createEditor
-
@VRonin
Here it is:#include "mydelegate.h" #include "imagepickbutton.h" #include "imagedelegate.h" myDelegate::myDelegate(QObject *parent):QStyledItemDelegate (parent) { } QWidget *myDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); if((index.column () == 1)) { QLineEdit *editor = new QLineEdit(parent); editor->setFrame (true); editor->setStyleSheet ("background-color:rgb(255,217,229)"); editor->resize (100,20); editor->sizeHint (); // connect(editor,&QLineEdit::editingFinished,this,&myDelegate::commitAndCloseEditor); return editor; } if((index.column () == 2)) { QComboBox *comboEditor = new QComboBox(parent); comboEditor->setFrame (true); comboEditor->setEditable (true); comboEditor->setStyleSheet ("background-color:rgb(255,217,229)"); QSqlQuery query_loadWhat ("SELECT What FROM What_Table ORDER BY What asc",db); while (query_loadWhat.next ()) { QString whatItem = query_loadWhat.value (0).toString (); comboEditor->addItem (whatItem); } return comboEditor; } if((index.column () == 3))//image { return new ImagePickButton(parent); } if(index.column () == 8)//Signed { QComboBox *comboSignedEdit = new QComboBox(parent); comboSignedEdit->setFrame (true); comboSignedEdit->setEditable (true); comboSignedEdit->setStyleSheet ("background-color:rgb(255,217,229)"); QSqlQuery query_loadSigned ("SELECT Signedby FROM Signed_Table ORDER BY Signedby asc",db); while (query_loadSigned.next ()) { QString SignedItem = query_loadSigned.value (0).toString (); comboSignedEdit->addItem (SignedItem); } return comboSignedEdit; } if (index.column () == 9)//History { QTextEdit *historyEditor = new QTextEdit(parent); historyEditor->frameRect (); historyEditor->setStyleSheet ("background-color:rgb(255,217,229)"); return historyEditor; } if(index.column () == 10) //Age { QLineEdit *editor = new QLineEdit(parent); editor->setFrame (true); editor->setStyleSheet ("background-color:rgb(255,217,229)"); editor->resize (100,20); editor->sizeHint (); return editor; } QTextEdit *notesEditor = new QTextEdit(parent); notesEditor->frameRect (); notesEditor->setStyleSheet ("background-color:rgb(255,217,229)"); return notesEditor; } void myDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QLineEdit *edit = qobject_cast<QLineEdit*>(editor); if(edit) { edit->setText (index.model ()->data (index,Qt::EditRole).toString ()); QVariant z(index.data (Qt::DisplayRole)); QString text; text = z.toString (); qDebug() << "edit: " << text; return; } QDateEdit *dateEditor = qobject_cast<QDateEdit*>(editor); if(dateEditor) { dateEditor->setDate (index.model ()->data (index, Qt::EditRole).toDate ()); dateEditor->setDate (QDate::fromString (index.model()->data (index,Qt::EditRole).toString (),"MM/dd/yyyy")); QVariant d(index.data (Qt::EditRole)); qDebug() << "QVariant adoption date: " << d; ImagePickButton* imgPick = qobject_cast<ImagePickButton*>(editor); Q_ASSERT(imgPick); imgPick->setSelectedFile(index.data(Qt::UserRole).toString()); return; } if((index.column () == 4))//material { QComboBox *comboMaterialEdit = new QComboBox(); comboMaterialEdit->setFrame (true); comboMaterialEdit->setEditable (true); comboMaterialEdit->setStyleSheet ("background-color:rgb(255,217,229)"); QSqlQuery query_loadMaterial ("SELECT Material FROM MaterialTable ORDER BY Material asc",db); while (query_loadMaterial.next ()) { QString whatItem = query_loadMaterial.value (0).toString (); comboMaterialEdit->addItem (whatItem); } return; } if((index.column() == 5))//color { QComboBox *comboColorEdit = new QComboBox(); comboColorEdit->setFrame (true); comboColorEdit->setEditable (true); comboColorEdit->setStyleSheet ("background-color:rgb(255,217,229)"); QSqlQuery query_loadColor ("SELECT Color FROM ColorTable ORDER BY Color asc",db); while (query_loadColor.next ()) { QString whatItem = query_loadColor.value (0).toString (); comboColorEdit->addItem (whatItem); } return; } if(index.column () == 6)//Description { QTextEdit *textEditor = new QTextEdit(); textEditor->frameRect (); textEditor->setStyleSheet ("background-color:rgb(255,217,229)"); return; } if(index.column () == 7)//Date { QDateEdit *deditor = new QDateEdit(); deditor->setDisplayFormat ("MM/dd/yyyy"); deditor->setCalendarPopup (true); deditor->setStyleSheet ("background-color:rgb(255,217,229)"); // connect(deditor,&QDateEdit::editingFinished ,this,&myDelegate::commitAndCloseEditor ); return; } QComboBox *comboEditor = qobject_cast<QComboBox*>(editor); if(comboEditor) { comboEditor->setCurrentText ((index.model ()->data (index, Qt::EditRole).toString ())); } QTextEdit *textEditor = qobject_cast<QTextEdit*>(editor); if(textEditor) { textEditor->setText ((index.model ()->data (index, Qt::EditRole).toString ())); } } void myDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QSqlQuery fixquery; int colset = index.column (); switch(colset) { case 1://Name { QLineEdit *edit = qobject_cast<QLineEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; model->setData (index,edit->text ()); QVariant f(index.data(Qt::DisplayRole)); QString modified; modified = f.toString (); qDebug() << "Modified: " << modified; fixquery.prepare("UPDATE Items SET Name = :Name WHERE ID = :fixID"); fixquery.bindValue (":Name", modified); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } case 2://What { QComboBox *comboEdit = qobject_cast<QComboBox*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ()));//setting index to ID QString fixID; QVariant w(updateIndex.data (Qt::DisplayRole));//getting data from index location fixID = w.toString (); //turning index data ID from QVariant to string qDebug() << "FixID: " << fixID; //getting ID QString saveWhat; saveWhat = comboEdit->currentText (); model->setData (index,saveWhat); QVariant ws(index.data (Qt::DisplayRole)); saveWhat = ws.toString (); saveWhat = saveWhat.simplified (); qDebug() << "saveWhat: " << saveWhat; fixquery.prepare("UPDATE Items SET What = :What WHERE ID = :fixID"); fixquery.bindValue (":What", saveWhat); fixquery.bindValue (":fixID",fixID); fixquery.exec (); fixquery.prepare ("INSERT OR IGNORE INTO What_Table (What)" "VALUES(:What)"); fixquery.bindValue (":What",saveWhat); fixquery.exec (); break; } case 3: //image { break; } case 4://material { QComboBox *comboMat = qobject_cast<QComboBox*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ()));//setting index to ID QString fixID; QVariant w(updateIndex.data (Qt::DisplayRole));//getting data from index location fixID = w.toString (); //turning index data ID from QVariant to string qDebug() << "FixID: " << fixID; //getting ID QString saveMat; saveMat = comboMat->currentText (); model->setData (index,saveMat); QVariant mat(index.data (Qt::DisplayRole)); saveMat = mat.toString (); saveMat = saveMat.simplified (); qDebug() << "saveMat: " << saveMat; fixquery.prepare("UPDATE Items SET Material = :Material WHERE ID = :fixID"); fixquery.bindValue (":Material", saveMat); fixquery.bindValue (":fixID",fixID); fixquery.exec (); fixquery.prepare ("INSERT OR IGNORE INTO MaterialTable (Material)" "VALUES(:Material)"); fixquery.bindValue (":Material",saveMat); fixquery.exec (); break; } case 5://color { QComboBox *comboColor = qobject_cast<QComboBox*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ()));//setting index to ID QString fixID; QVariant w(updateIndex.data (Qt::DisplayRole));//getting data from index location fixID = w.toString (); //turning index data ID from QVariant to string qDebug() << "FixID: " << fixID; //getting ID QString saveColor; saveColor = comboColor->currentText (); model->setData (index,saveColor); QVariant mat(index.data (Qt::DisplayRole)); saveColor = mat.toString (); saveColor = saveColor.simplified (); qDebug() << "saveMat: " << saveColor; fixquery.prepare("UPDATE Items SET Color = :Color WHERE ID = :fixID"); fixquery.bindValue (":Color", saveColor); fixquery.bindValue (":fixID",fixID); fixquery.exec (); fixquery.prepare ("INSERT OR IGNORE INTO ColorTable (Color)" "VALUES(:Color)"); fixquery.bindValue (":Color",saveColor); fixquery.exec (); break; } case 6: //description { QTextEdit *tedit = qobject_cast<QTextEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; QString descString; descString = tedit->toPlainText (); model->setData (index,descString); QVariant desc(index.data(Qt::DisplayRole)); QString DescModified; DescModified = desc.toString (); qDebug() << "Description: " << DescModified; fixquery.prepare("UPDATE Items SET Description = :Description WHERE ID = :fixID"); fixquery.bindValue (":Description", DescModified); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } case 7://date { QDateEdit *dateEdit = qobject_cast<QDateEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; model->setData (index,dateEdit->date ().toString ("MM/dd/yyyy"),Qt::EditRole); QVariant d(index.data (Qt::EditRole)); QString modDate; modDate = d.toString (); qDebug() << "modDate: " << modDate; fixquery.prepare("UPDATE Items SET AdoptDate = :AdoptDate WHERE ID = :fixID"); fixquery.bindValue (":AdoptDate", modDate); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } case 8://Signed by { QComboBox *comboSigned = qobject_cast<QComboBox*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ()));//setting index to ID QString fixID; QVariant w(updateIndex.data (Qt::DisplayRole));//getting data from index location fixID = w.toString (); //turning index data ID from QVariant to string qDebug() << "FixID: " << fixID; //getting ID QString saveSigned; saveSigned = comboSigned->currentText (); model->setData (index,saveSigned); QVariant sign(index.data (Qt::DisplayRole)); saveSigned = sign.toString (); saveSigned = saveSigned.simplified (); qDebug() << "saveMat: " << saveSigned; fixquery.prepare("UPDATE Items SET Signed = :Signed WHERE ID = :fixID"); fixquery.bindValue (":Signed", saveSigned); fixquery.bindValue (":fixID",fixID); fixquery.exec (); fixquery.prepare ("INSERT OR IGNORE INTO Signed_Table (Signedby)" "VALUES(:Signedby)"); fixquery.bindValue (":Color",saveSigned); fixquery.exec (); break; } case 9://History { QTextEdit *histEdit = qobject_cast<QTextEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; QString histString; histString = histEdit->toPlainText (); model->setData (index,histString); QVariant hist(index.data(Qt::DisplayRole)); QString histModified; histModified = hist.toString (); qDebug() << "History: " << histModified; qDebug() << "Db connection names (history):" << db.connectionName (); fixquery.prepare("UPDATE Items SET History = :History WHERE ID = :fixID"); fixquery.bindValue (":History", histModified); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } case 10://Age { QLineEdit *edit = qobject_cast<QLineEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; model->setData (index,edit->text ()); QVariant a(index.data(Qt::DisplayRole)); QString modAge; modAge = a.toString (); qDebug() << "Modified: " << modAge; fixquery.prepare("UPDATE Items SET Age = :Age WHERE ID = :fixID"); fixquery.bindValue (":Age", modAge); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } case 11: //notes { QTextEdit *noteEdit = qobject_cast<QTextEdit*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ())); QString fixID; QVariant v(updateIndex.data (Qt::DisplayRole)); fixID = v.toString (); qDebug() << "FixID: " << fixID; QString noteString; noteString = noteEdit->toPlainText (); model->setData (index,noteString); QVariant n(index.data(Qt::DisplayRole)); QString noteModified; noteModified = n.toString (); qDebug() << "History: " << noteModified; fixquery.prepare("UPDATE Items SET Notes = :Notes WHERE ID = :fixID"); fixquery.bindValue (":Notes", noteModified); fixquery.bindValue (":fixID",fixID); fixquery.exec (); break; } } } void myDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index); editor->setGeometry (option.rect); } QSize myDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); QVariant value = index.data(Qt::SizeHintRole); } void myDelegate::commitAndCloseEditor() { qDebug() << "Commit and close works!"; QLineEdit *editor = qobject_cast<QLineEdit*>(sender()); emit commitData(editor); emit closeEditor(editor); QDateEdit *deditor = qobject_cast<QDateEdit*>(sender ()); emit commitData (deditor); emit closeEditor (deditor); } QByteArray myDelegate::getNewPix() { { qDebug() << "Entered getNewPix!"; QString sPath = "C:/"; // fileDialog = getOpenFileName (Q_NULLPTR,sPath); const QString fileName = QFileDialog::getOpenFileName(Q_NULLPTR, tr("Finding Friend's replacement Image"),sPath, tr("Image Files (*.png *.jpg *.bmp)")); if(fileName == "") { qDebug() << "No image was chosen."; } else { qDebug() << "Image was chosen!"; } QFile file(fileName); } } QString myDelegate::getText() { QString Test; Test = "This is a test!"; return Test; }
-
@gabor53 I don't see anything obvious in the code. It looks ok.
What does the debugger say as you step through that createEditor? Is your pointer to parent ok? Not null? Points at a valid QObject? You reference index, is
index.isValid()
true?Exactly what line does it crash on in the debugger?
-
if(index.column()==
inside a delegate is always bad design. could you step through with a debugger to see where it breaks? could you also post the constructor of ImagePickButton? -
@VRonin
I deleted the build folder and reran qmake and build. Now the program crashes and gives a SIGSEGV error when execution reaches this section of the code:case 4://material { QComboBox *comboMat = qobject_cast<QComboBox*>(editor); QModelIndex updateIndex(index.model ()->index(index.row (),0,index.parent ()));//setting index to ID QString fixID; QVariant w(updateIndex.data (Qt::DisplayRole));//getting data from index location fixID = w.toString (); //turning index data ID from QVariant to string qDebug() << "FixID: " << fixID; //getting ID QString saveMat; saveMat = comboMat->currentText (); model->setData (index,saveMat); QVariant mat(index.data (Qt::DisplayRole)); saveMat = mat.toString (); saveMat = saveMat.simplified (); qDebug() << "saveMat: " << saveMat; fixquery.prepare("UPDATE Items SET Material = :Material WHERE ID = :fixID"); fixquery.bindValue (":Material", saveMat); fixquery.bindValue (":fixID",fixID); fixquery.exec (); fixquery.prepare ("INSERT OR IGNORE INTO MaterialTable (Material)" "VALUES(:Material)"); fixquery.bindValue (":Material",saveMat); fixquery.exec (); break; }
It stops at this line:
saveMat = comboMat->currentText ();
Where should if(index.column()== go?
Thank you. -
@gabor53 More than likely comboMat is invalid at that point. Either it's null or a dangling pointer. Or it was an uninitialized one.
Either way it's a bad pointer. Confirm in the debugger then dig through your code to find out why.
-
@dheerendra said in Assigning ItemDelegates to different columns in a view:
It is correct. I don't see any issue. Also can try not passing the this as parent to delegate. Also whether both the delegates work if you specify them individually