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. Apparently setParent would crash without obvious reasons and no illegal pointers

Apparently setParent would crash without obvious reasons and no illegal pointers

Scheduled Pinned Locked Moved Solved General and Desktop
qtabwidgettabqsplitter
5 Posts 2 Posters 149 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.
  • J Offline
    J Offline
    JackMyson
    wrote last edited by
    #1

    So to make long story short here's the thing: I've somehow managed to make a tab splitter application and apparently I've figured out a way to move the tabs between the splitters and even windows. Now the real problem is whenever I make the tab moves by performing this trick:

        TpTabWidget *newTab = new TpTabWidget(splitter);
        splitter->addTab(newTab);
        oldTab->removeEditor(editor, true);
        newTab->addEditor(editor);
    

    The app will crash on the addEditor part. And for a holistic view here's my relevant code. (For the prefix part you may just treat the Tp as a variant of Q of subclassed Qt classes for the purpose of customising different functions)

    void TpMainWindow::onAction_V_L_M(bool)
    {
        TpTabWidget *oldTab = m_widget->tabs()->tab();
    
        if (!oldTab || oldTab->count() <= 1)
            return;
    
        TpEditor *editor = oldTab->tab();
        TpTabSplitter *splitter = m_widget->tabs();
    
        if (!editor)
            return;
    
        TpTabWidget *newTab = new TpTabWidget(splitter);
        splitter->addTab(newTab);
        oldTab->removeEditor(editor, true);
        newTab->addEditor(editor);
    
        updateEditorsMap();
        splitter->update();
        m_widget->update();
    }
    
    TpEditor *TpTabWidget::addEditor(TpEditor *editor)
    {
        editor->disconnect();
    
        QFileIconProvider provider;
        const QIcon &fileIcon = provider.icon(QFileIconProvider::IconType::File);
    
        QString text;
    
        if (editor->filePath() == "")
            text = QString("Untitled %1").arg(editor->m_untitled);
        else
            text = QFileInfo(QFile(editor->filePath())).fileName();
    
        editor->m_parent = this;
        editor->setParent(this);
        int index = addTab(editor, fileIcon, text);
    
        setTabToolTip(index, text);
        setCurrentIndex(index);
    
        connect(editor,
                &TpEditor::fileNameChanged,
                m_parent->m_parent->m_parent,
                &TpMainWindow::onEditorFileNameChanged);
        connect(editor,
                &TpEditor::checkBoxChecked,
                m_parent->m_parent->m_parent,
                &TpMainWindow::onEditorCheckBoxChecked);
        connect(editor,
                &TpEditor::positionChanged,
                m_parent->m_parent->m_parent,
                &TpMainWindow::onEditorPositionChanged);
        connect(editor,
                SIGNAL(selectionChanged()),
                m_parent->m_parent->m_parent,
                SLOT(onEditorSelectionChanged()));
        connect(editor,
                &TpEditor::punctuation,
                m_parent->m_parent->m_parent,
                &TpMainWindow::onEditorPunctuation);
    
        DEF_SETTINGS;
    
        editor->setAutoCompletionThreshold(GET_SETTINGS("Editor/Values/AutoCompletionThreshold", int));
        editor->setCallTipsVisible(GET_SETTINGS("Editor/Values/CallTipsMaximum", int));
        editor->setCaretWidth(GET_SETTINGS("Editor/Values/CaretLineWidth", int));
        editor->setEdgeColumn(GET_SETTINGS("Editor/Values/EdgeColumn", int));
        editor->setExtraAscent(GET_SETTINGS("Editor/Values/ExtraAscent", int));
        editor->setExtraDescent(GET_SETTINGS("Editor/Values/ExtraDescent", int));
        editor->setTabWidth(GET_SETTINGS("Editor/Values/TabWidth", int));
        editor->setIndentationWidth(GET_SETTINGS("Editor/Values/TabWidth", int));
    
        emit m_parent->tabsListChanged(m_parent->m_tabs.length());
    
        emit editor->fileNameChanged(editor->m_filePath, text);
        editor->setFocus();
    
        return editor;
    }
    
    void TpTabWidget::removeEditor(TpEditor *editor, bool noDelete)
    {
        if (indexOf(editor) < 0)
        {
            Q_ASSERT_X(false, Q_FUNC_INFO, "Editor not in the tab widget.");
            return;
        }
    
        editor->disconnect();
        removeTab(indexOf(editor));
    
        emit m_parent->tabsListChanged(m_parent->m_tabs.length());
    
        if (!noDelete)
        {
            editor->m_parent = nullptr;
            // editor->deleteLater();
            delete editor;
        }
    }
    
    void TpTabWidget::onBarDragged()  // <-- slot emitted when the tab bar detects dragging and want to move from and to tabs, from and to windows
    {
        QDrag *drag = new QDrag(this);
        QMimeData *mimeData = new QMimeData;
        int key = m_keyValue++;
        m_dragInfo.insert(key, {m_bar->tabToolTip(currentIndex()), tab()});
        mimeData->setData(tabMimeType, QByteArray::number(key));
        QPixmap pixmap = currentWidget()->grab();
        drag->setMimeData(mimeData);
        drag->setPixmap(pixmap);
        Qt::DropAction action = drag->exec(Qt::DropAction::CopyAction | Qt::DropAction::MoveAction);
    
        if (action == Qt::DropAction::IgnoreAction)
        {
            if (count() <= 1)
                return;
            TpMainWindow *newWindow = new TpMainWindow(false, false, tab());
            newWindow->show();
            m_parent->m_parent->m_parent->updateDocumentDock();
        }
    }
    
    void TpTabWidget::dragEnterEvent(QDragEnterEvent *event)
    {
        const QMimeData *mime = event->mimeData();
        if (mime->hasUrls() || mime->hasText() || mime->hasFormat(tabMimeType))
            event->acceptProposedAction();
    }
    
    void TpTabWidget::dropEvent(QDropEvent *event)
    {
        const QMimeData *mimeData = event->mimeData();
    
        if (mimeData)
        {
            if (mimeData->hasUrls())
            {
                event->acceptProposedAction();
                QStringList sl;
                for (const auto &item : mimeData->urls())
                    if (item.isLocalFile())
                        sl << item.toLocalFile();
                if (sl.empty())
                    goto acceptor;
    
                TpOpenAssistant *assistant = new TpOpenAssistant(m_parent->m_parent->m_parent);
                assistant->openFiles(sl);
                event->accept();
                return;
            }
    
            else if (mimeData->hasText())
            {
                event->acceptProposedAction();
                tab()->insert(mimeData->text());
                event->accept();
                return;
            }
    
            else if (mimeData->hasFormat(tabMimeType))
            {
                event->acceptProposedAction();
                int key = mimeData->data(tabMimeType).toInt();
                auto it = m_dragInfo.find(key);
                if (it == m_dragInfo.end())
                    goto acceptor;
                TpTabInfo info = it.value();
                m_dragInfo.erase(it);
                int idx = m_bar->tabAt(event->position().toPoint());
                TpEditor *ed = info.widget();
                ed->m_parent->removeEditor(ed, true);
                addEditor(ed);
    
                if (idx < count() && idx >= 0)
                {
                    m_bar->moveTab(currentIndex(), idx);
                    setCurrentIndex(idx);
                }
    
                m_parent->m_parent->m_parent->updateDocumentDock();
                event->accept();
                return;
            }
        }
    
        goto acceptor;
    
        acceptor:
            QTabWidget::dropEvent(event);
    }
    

    The tabMimeType is just a string I've defined to differentiate between text and so, and to facilitate dragging solely by QMimeType:

    inline constexpr const char *const tabMimeType = "application/x-tabwidget.index";
    

    The debug information didn't show any illegal pointers or so. Fyr in Qt Creator for example, everything the debugger has shown was in grey and didn't have any problem I presume. Worse still if I comment out the setParent line it'll be addTab's crash later on. I till now sadly couldn't still diagnose what kind of problems is occurring.

    Huge thanks to anyone who could help me, thanks to all help, thanks in advance.
    If you want more code to help me please don't hesitate to demand down below

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JackMyson
      wrote last edited by
      #5

      The problem has been solved. So it turns out that the onTabsListChanged is the ultimate culprit that made the app crash. Seemingly the thing has been called multiple times due to the signal it bound to has been emitted multiple times also, resulting removing tab that has already been removed. Now I just have to remove the code or comment it out at least to resolve the issue.

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote last edited by
        #2

        What does removeEditor() do? I would guess it deletes the widget.
        Please provide a minimal, compilable example to reproduce your problem.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JackMyson
          wrote last edited by
          #3

          Oh, the removeEditor is just

          void TpTabWidget::removeEditor(TpEditor *editor, bool noDelete)
          {
              if (indexOf(editor) < 0)
              {
                  Q_ASSERT_X(false, Q_FUNC_INFO, "Editor not in the tab widget.");
                  return;
              }
          
              editor->disconnect();
              removeTab(indexOf(editor));
          
              emit m_parent->tabsListChanged(m_parent->m_tabs.length());
          
              if (!noDelete)
              {
                  editor->m_parent = nullptr;
                  // editor->deleteLater();
                  delete editor;
              }
          }
          

          Where you preserve and do not delete the editor when you pass in the true parameter at the end of the method.

          1 Reply Last reply
          0
          • J Offline
            J Offline
            JackMyson
            wrote last edited by
            #4

            Btw the tabListChanged

            void TpMainWindow::onTabsListChanged(int length)
            {
                if (length > 0)
                {
                    for (const auto &tab : m_widget->tabs()->m_tabs)
                        if (tab->count() <= 0)
                            m_widget->tabs()->removeTab(tab);
                }
            }
            

            I'm not sure if it relates, but I added it later on when I attempted to extend the functionalities of cross-parent tab dragging where you normally have to update and do whatever parent-shifting as one would normally do in Qt. Only then did it crash, before it was running properly and I could dissect one tab into two or three or more.

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JackMyson
              wrote last edited by
              #5

              The problem has been solved. So it turns out that the onTabsListChanged is the ultimate culprit that made the app crash. Seemingly the thing has been called multiple times due to the signal it bound to has been emitted multiple times also, resulting removing tab that has already been removed. Now I just have to remove the code or comment it out at least to resolve the issue.

              1 Reply Last reply
              0
              • J JackMyson has marked this topic as solved

              • Login

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