Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Crash in takeChild() while deleting a QTreeWidgetItem
QtWS25 Last Chance

Crash in takeChild() while deleting a QTreeWidgetItem

Scheduled Pinned Locked Moved General and Desktop
25 Posts 5 Posters 14.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LAXMIU
    wrote on last edited by
    #2

    ModelForm.cpp
    @
    #include "ModelForm.h"

    ModelForm::ModelForm( QWidget* parent, Qt::WFlags fl):QWidget( parent, fl )
    {
    modelTree=new QTreeWidget;
    QGridLayout *mainLayout = new QGridLayout;
    QVBoxLayout *VLayout = new QVBoxLayout;
    VLayout->setMargin(0);
    mainLayout->setMargin(0);
    VLayout->addWidget(modelTree,0);
    mainLayout->addLayout(VLayout, 0,0);
    setLayout(mainLayout);
    _delegate = NULL;
    globalModels = NULL;

    _delegate = new ModelFormDelegate(modelTree,modelTree,this);
    modelTree->setItemDelegate(_delegate);
    modelTree->setColumnCount(3);
    modelTree->header()->resizeSection(CHECKBOXCOL,60);
    modelTree->header()->resizeSection(FILENAMECOL,400);
    modelTree->header()->setResizeMode(FILENAMECOL, QHeaderView::Stretch);
    modelTree->header()->setResizeMode(CHECKBOXCOL, QHeaderView::Interactive);
    modelTree->header()->setResizeMode(SECTIONCOL, QHeaderView::Interactive);
    modelTree->header()->setStretchLastSection(false);
    modelTree->setContextMenuPolicy(Qt::CustomContextMenu);
    modelTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
    modelTree->setTextElideMode(Qt::ElideLeft);
    modelTree->setEditTriggers(QAbstractItemView::AllEditTriggers);
    

    modelTree->setTabKeyNavigation(true);

    QStringList labels;
    labels << "" << "Model File" << "Section";
    modelTree->setHeaderLabels(labels);
    
     resetModelForm();
           
     connect( _delegate, SIGNAL( addModelFilesSignal(const QStringList&) ),
       this, SLOT(  addModelFilesSlot(const QStringList&) ) );
     connect( modelTree, SIGNAL( itemChanged(QTreeWidgetItem *, int) ),
       this, SLOT(  itemChanged(QTreeWidgetItem *,int) ) );
     connect(this, SIGNAL(deleteRow(QTreeWidgetItem*, int)), this, SLOT(deleteRowSlot(QTreeWidgetItem*, int)));
    
     if (!parent) show();
    

    }

    bool ModelForm::event(QEvent *event)
    {
    if(event->type() == QEvent::Leave) {
    QTreeWidgetItem *item = modelTree->currentItem();
    if(item != NULL){
    int col = modelTree->currentColumn();
    ModelFileEditor *fileEdit = qobject_cast<ModelFileEditor *>(modelTree->itemWidget(item,col));
    QLineEdit *lineEdit = qobject_cast<QLineEdit *>(modelTree->itemWidget(item,col));
    if(fileEdit){
    if(item->text(col) != fileEdit->lineEdit->text()){
    item->setText(col,fileEdit->lineEdit->text());
    }
    }
    else if(lineEdit){
    if(item->text(col) != lineEdit->text()){
    item->setText(col,lineEdit->text());
    }
    }
    }
    }
    return QWidget::event(event);
    }

    void ModelForm::resetModelForm() {
    modelTree->clearSelection();
    QTreeWidgetItem* current = modelTree->currentItem();
    if(current) {
    modelTree->closePersistentEditor(current,FILENAMECOL);
    }
    modelTree->clear();
    globalModels = new QTreeWidgetItem;
    modelTree->blockSignals(true);
    globalModels->setText(BLOCKCOL,GLOBALBLOCKNAME);
    globalModels->setFlags(Qt::ItemIsEnabled|Qt::ItemIsUserCheckable);
    modelTree->blockSignals(false);
    modelTree->addTopLevelItem(globalModels);
    addBlankRow(globalModels);
    }

    void ModelForm::addBlankRow(QTreeWidgetItem* item) {
    QTreeWidgetItem* chItem = new QTreeWidgetItem;

    item->addChild(chItem);
    modelTree->expandItem(item);
    modelTree->blockSignals(true);
    chItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable);
    chItem->setCheckState(CHECKBOXCOL,Qt::Unchecked);
    chItem->setText(FILENAMECOL,QString(EMPTYROWTEXT));
    modelTree->blockSignals(false);
    }

    QTreeWidgetItem* ModelForm::getBlockItem( QString blockName) {
    if(QString::compare(QString(GLOBALBLOCKNAME),blockName) == 0) {
    return globalModels;
    } else {
    int itemCount = modelTree->topLevelItemCount();
    for(int i=0; i<itemCount;i++) {
    if(QString::compare(modelTree->topLevelItem(i)->text(BLOCKCOL),blockName) == 0) {
    return modelTree->topLevelItem(i);
    }
    }
    }
    return NULL;
    }
    void ModelForm::itemChanged( QTreeWidgetItem * item,int col) {
    if(col == FILENAMECOL) {
    QString file = item->text(FILENAMECOL);
    if(item->parent() != NULL) {
    QTreeWidgetItem* p = item->parent();
    int index = p->indexOfChild(item);
    if((index == p->childCount() -1) && (file != QString(EMPTYROWTEXT))) {
    if(file.isEmpty()){
    modelTree->blockSignals(true);
    item->setText(FILENAMECOL,QString(EMPTYROWTEXT));
    modelTree->blockSignals(false);
    }
    else {
    item->setFlags(item->flags()|Qt::ItemIsSelectable);
    item->setCheckState(CHECKBOXCOL,Qt::Checked);
    addBlankRow(p);
    }
    } else if( index != p->childCount() -1 && (file.isEmpty() || file == QString(EMPTYROWTEXT))) {
    // delete this row
    emit deleteRow(p, index);
    }
    }
    }
    }

    //Modified below function so that files are inserted instead of adding it at last.
    void ModelForm::addModelFilesSlot(const QStringList& paths){
    QTreeWidgetItem* curItem = NULL;
    curItem = modelTree->currentItem();
    int curCol = modelTree->currentColumn();
    // if curItem is not toplevel item
    if(curItem && (curCol !=-1) && (modelTree->indexOfTopLevelItem(curItem) == -1)) {
    QTreeWidgetItem* parent = curItem->parent();
    if(parent){
    int childIndex = parent->indexOfChild(curItem);
    for (int i = 0; i < paths.size(); ++i) {
    QTreeWidgetItem* child = new QTreeWidgetItem();
    child->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable |
    Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable);
    child->setCheckState(CHECKBOXCOL,Qt::Checked);
    child->setText(FILENAMECOL,(paths.at(i)));
    parent->insertChild(((childIndex+1)+i), child);
    }
    }
    }
    }

    void ModelForm::deleteRowSlot(QTreeWidgetItem* item , int index) {
    QTimer::singleShot(1, this, SLOT(deleteCurrent()));
    }
    @

    [edit: highlight added / Denis Kormalev]

    1 Reply Last reply
    0
    • L Offline
      L Offline
      LAXMIU
      wrote on last edited by
      #3

      @
      void ModelForm::deleteCurrent() {
      QList<QTreeWidgetItem *> itemList = modelTree->selectedItems();
      modelTree->blockSignals(true);
      for(int i= 0; i <itemList.size(); i++) {
      if(itemList.at(i) != NULL && itemList.at(i)->parent() != NULL) {
      QTreeWidgetItem *c=itemList.at(i);
      QTreeWidgetItem p = c->parent();
      c= p->takeChild(p->indexOfChild(c));
      delete c;
      if( modelTree->isItemExpanded(p)) {
      modelTree->collapseItem(p);
      modelTree->expandItem(p);
      }
      }
      }
      modelTree->blockSignals(false);
      //now select the current item
      QTreeWidgetItem
      curItem = modelTree->currentItem();
      if(curItem){
      modelTree->setItemSelected(curItem, true);
      }
      }
      @

      [edit: highlight added / Denis Kormalev]

      1 Reply Last reply
      0
      • L Offline
        L Offline
        LAXMIU
        wrote on last edited by
        #4

        ModelFormDelegate.cpp
        @
        #include <QtGui/QtGui>

        #include "ModelFormDelegate.h"
        #include "ModelForm.h"

        QString ModelFileEditor::lastFilePath = NULL;

        ModelFileEditor::ModelFileEditor( QWidget* parent, ModelForm* qwidget, Qt::WFlags fl )
        :QWidget( parent, fl ), _parent(qwidget)
        {
        lineEdit = new QLineEdit;
        lineEdit->setFrame(FALSE);
        btn = new QPushButton(QString(" ... "));
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->setMargin(0);
        mainLayout->setSpacing(0);
        mainLayout->addWidget(lineEdit,5);
        mainLayout->addWidget(btn,0);
        mainLayout->addSpacing(5);
        setLayout(mainLayout);
        connect(lineEdit, SIGNAL(editingFinished()), this, SIGNAL(editingFinished()));
        connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(editingFinishedSlot()));
        connect(lineEdit, SIGNAL(textChanged(const QString &) ),this, SLOT(textChangedSlot( const QString &)));
        this->setFocusProxy(lineEdit);
        setTabOrder(lineEdit,btn);
        }

        void ModelFileEditor::editingFinishedSlot() {
        f(lineEdit) {
        if((lineEdit->text() != QString(EMPTYROWTEXT)) && (lineEdit->text() != QString(""))) {

        QString temp(FILESTR);
        

        temp.append(lineEdit->text());
        temp.append(NOTEXIST);
        lineEdit->setToolTip(temp);
        }
        }
        }

        void ModelFileEditor::textChangedSlot( const QString & text){
        if(lineEdit){
        lineEdit->setToolTip(text);
        }
        editingFinishedSlot();
        }

        ModelFormDelegate::ModelFormDelegate(QObject *parent)
        : QItemDelegate(parent),m_view(NULL){}

        ModelFormDelegate::ModelFormDelegate(QObject *parent, QAbstractItemView *aiv,ModelForm *qwidget)
        : QItemDelegate(parent),m_view(aiv),_parent(qwidget){}

        void ModelFormDelegate::paint(QPainter *painter,
        const QStyleOptionViewItem &option,
        const QModelIndex &index) const
        {
        int col = index.column();
        int row = index.row();
        int pRow = index.parent().row();
        if (index.isValid() && !index.parent().isValid()) {
        QModelIndex index2(index.sibling(index.row(),0));
        QStyleOptionViewItem sovi(option);
        sovi.rect=QRect(0, option.rect.y(),
        painter->viewport().width(),
        option.rect.height());
        if(m_view)
        sovi.rect.setX(m_view->visualRect(index2).x());
        QItemDelegate::paint(painter,sovi,index2);
        } else {
        int rows = -1;
        if(m_view)
        {
        rows = qobject_cast<QTreeWidget *>(m_view)->topLevelItem(pRow)->childCount();
        }
        QModelIndex lastRowIndex(index.sibling(rows-1,col));
        QModelIndex lastColIndex(index.sibling(row,2));
        int w = option.rect.width();
        int h = option.rect.height();
        if(index == lastRowIndex)
        {
        h= h-1;
        }
        if(index == lastColIndex)
        {
        w= w-1;
        }
        QItemDelegate::paint(painter, option, index);
        painter->setPen(QColor(Qt::lightGray));
        QRect myrect(option.rect.x(),option.rect.y(),w,h);
        painter->drawRect(myrect);
        }
        }
        QWidget *ModelFormDelegate::createEditor(QWidget parent,
        const QStyleOptionViewItem & /
        option */,
        const QModelIndex &index) const
        {
        int col = index.column();

        if( !index.parent().isValid()) return NULL;

        if(col == 2 ) { // section
        QLineEdit *lineEdit = new QLineEdit(parent);
        connect( lineEdit, SIGNAL(editingFinished()), this , SLOT(emitCommitData()));
        return lineEdit;
        } else if(col == 0 ){// checkBox
        return NULL;
        } else if(col == 3 ){// push button for browser
        QPushButton * pushButton = new QPushButton(QString("..."),parent);
        connect(pushButton, SIGNAL(clicked()), this, SLOT(emitCommitData()));
        return pushButton;
        } else if(col == 1 ){ //file
        ModelFileEditor *fileEdit = new ModelFileEditor(parent,_parent);
        connect(fileEdit, SIGNAL(editingFinished()), this, SLOT(emitCommitData()));
        connect(fileEdit, SIGNAL(addModelFiles(const QStringList&)), this, SLOT(addModelFiles(const QStringList&)));
        return fileEdit;
        } else {
        return NULL;
        }
        return NULL;
        }

        void ModelFormDelegate::setEditorData(QWidget *editor,
        const QModelIndex &index) const
        {
        int col = index.column();
        if(col == 2 ) {
        QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
        if( !lineEdit) {
        return;
        }
        if((lineEdit->text())!= (index.model()->data(index).toString())) {
        lineEdit->setText(index.model()->data(index).toString());
        lineEdit->selectAll();
        }

        } else if(col == 1 ){
        ModelFileEditor *fileEdit = qobject_cast<ModelFileEditor *>(editor);
        if (!fileEdit) {
        return;
        }
        if ((fileEdit->lineEdit->text())!= (index.model()->data(index).toString())) {
        fileEdit->lineEdit->setText(index.model()->data(index).toString());
        }
        fileEdit->lineEdit->selectAll();

        } else if(col == 3 ){
        QPushButton *btn = qobject_cast<QPushButton *>(editor);
        if (!btn)
        return;
        }
        }

        void ModelFormDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
        const QModelIndex &index) const
        {
        int col = index.column();
        if(col == 2 ) {
        QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
        if( !lineEdit) {
        return;
        }
        model->setData(index, lineEdit->text());

        } else if(col == 1 ){
        ModelFileEditor *fileEdit = qobject_cast<ModelFileEditor *>(editor);
        if (!fileEdit) {
        return;
        }
        model->setData(index, fileEdit->lineEdit->text());
        } else if(col == 3 ){
        QPushButton *btn = qobject_cast<QPushButton *>(editor);
        if (!btn)
        return;
        model->setData(index, true);
        }
        }

        void ModelFormDelegate::addModelFiles(const QStringList& files)
        {
        emit addModelFilesSignal(files);
        }
        @

        [edit: highlight added / Denis Kormalev]

        1 Reply Last reply
        0
        • T Offline
          T Offline
          tobias.hunger
          wrote on last edited by
          #5

          Could you please use the code tags to format your code sections? It is hardly readable the way it is printed now!

          1 Reply Last reply
          0
          • T Offline
            T Offline
            thorbjorn
            wrote on last edited by
            #6

            This might have something to do with @modelTree->blockSignals(true);@, which I guess could cause the view not to be entirely aware of the child removals, but I'm not sure. In any case this forum is not the proper place to report bugs, you should use "http://bugreports.qt.nokia.com/":http://bugreports.qt.nokia.com/ for that.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              LAXMIU
              wrote on last edited by
              #7

              .

              1 Reply Last reply
              0
              • L Offline
                L Offline
                LAXMIU
                wrote on last edited by
                #8

                Hi,
                I tried removing blockSignals from the deleteCurrent functionality , but it did not work out.

                Thanks, Laxmi

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  LAXMIU
                  wrote on last edited by
                  #9

                  .

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    LAXMIU
                    wrote on last edited by
                    #10

                    .

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      DenisKormalev
                      wrote on last edited by
                      #11

                      LAXMIU, I've added highlighting to your code, please don't forget to use it by yourself in future :)

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        alexander
                        wrote on last edited by
                        #12

                        why do you use takeChild()?
                        try only delete item

                        @void ModelForm::deleteCurrent() {
                        QList<QTreeWidgetItem *> itemList = modelTree->selectedItems();
                        for(int i= 0; i <itemList.size(); i++) {
                        if(itemList.at(i) != NULL && itemList.at(i)->parent() != NULL) {
                        QTreeWidgetItem *c=itemList.at(i);
                        QTreeWidgetItem p = c->parent();
                        delete c;
                        }
                        }
                        //now select the current item
                        QTreeWidgetItem
                        curItem = modelTree->currentItem();
                        if(curItem){
                        modelTree->setItemSelected(curItem, true);
                        }
                        }@

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          LAXMIU
                          wrote on last edited by
                          #13

                          Hi Alexander,

                          I tried removing takeChild too, the crash now coming in the destructor of QTreeWidgetItem as follows:

                          #0 0x00270823 in QPersistentModelIndex::operator QModelIndex const& ()
                          from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtCore.so.4
                          #1 0x0120539f in QAbstractItemView::updateEditorGeometries () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #2 0x011f6dd2 in QAbstractItemViewPrivate::_q_rowsRemoved () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #3 0x0123deaa in QTreeViewPrivate::rowsRemoved () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #4 0x0123e4eb in QTreeView::rowsAboutToBeRemoved () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #5 0x01202865 in QAbstractItemView::qt_metacall () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #6 0x012492ba in QTreeView::qt_metacall () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #7 0x0128212a in QTreeWidget::qt_metacall () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #8 0x00291583 in QMetaObject::activate () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtCore.so.4
                          #9 0x002921e2 in QMetaObject::activate () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtCore.so.4
                          #10 0x002cb7ff in QAbstractItemModel::rowsAboutToBeRemoved () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtCore.so.4
                          #11 0x00272965 in QAbstractItemModel::beginRemoveRows () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtCore.so.4
                          #12 0x0127f4c6 in QTreeModel::beginRemoveItems () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #13 0x0127f6b0 in QTreeWidgetItem::~QTreeWidgetItem () from /net/ciclnx11d/export/home/laxmi/PERFORCE/DEL/lnx86/tools/Qt/32bit/lib/libQtGui.so.4
                          #14 0x0804c7da in ModelForm::deleteCurrent (this=0x857ff60) at ModelForm.cpp:179

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            LAXMIU
                            wrote on last edited by
                            #14

                            [quote author="Denis Kormalev" date="1285753913"]LAXMIU, I've added highlighting to your code, please don't forget to use it by yourself in future :)[/quote]

                            Hi Denis,
                            Please let me know the procedure/steps of highlighting the code. I really don't know. I am new to this forum. I could not either find any icon above for doing so.

                            Thanks andregards,
                            Laxmi

                            1 Reply Last reply
                            0
                            • ? This user is from outside of this forum
                              ? This user is from outside of this forum
                              Guest
                              wrote on last edited by
                              #15

                              just enclose only your code with the @ tag ... one before and one after your code :)

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                tobias.hunger
                                wrote on last edited by
                                #16

                                LAXMIU: ... or just mark the code with your mouse and click on the second icon from the right (the one with the tooltip "Code").

                                1 Reply Last reply
                                0
                                • T Offline
                                  T Offline
                                  tobias.hunger
                                  wrote on last edited by
                                  #17

                                  This thread kind of reminds me of computer magazines in the early 80ties...

                                  1 Reply Last reply
                                  0
                                  • D Offline
                                    D Offline
                                    DenisKormalev
                                    wrote on last edited by
                                    #18

                                    [quote author="Tobias Hunger" date="1286270859"]This thread kind of reminds me of computer magazines in the early 80ties...[/quote]

                                    A lot of code and small amount of text?:)

                                    1 Reply Last reply
                                    0
                                    • L Offline
                                      L Offline
                                      LAXMIU
                                      wrote on last edited by
                                      #19

                                      I have removed unnecessary repetition of code from the thread.
                                      Hopefully its readable now.

                                      Thanks,
                                      Laxmi

                                      1 Reply Last reply
                                      0
                                      • ? This user is from outside of this forum
                                        ? This user is from outside of this forum
                                        Guest
                                        wrote on last edited by
                                        #20

                                        ok laxmi, I copied all the code and tried on Qt 4.7, no crashes ... any specific reason you are still on Qt 4.5.x ?

                                        1 Reply Last reply
                                        0
                                        • L Offline
                                          L Offline
                                          LAXMIU
                                          wrote on last edited by
                                          #21

                                          Thanks a lot Chetan,

                                          We have migrated from 4.4.1 to 4.5.3 in one of our product releases. Hopefully, we will be getting the latest Qt version attached for our next product release.

                                          May I get any pointer that its actually a bug in Qt 4.5.3?
                                          Have you been able to reproduce the crash in Qt 4.5.3? (If thats available with you)

                                          Thanks,
                                          Laxmi

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved