Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    [SOLVED] Call of a subclassed QWidget method crashes the program

    General and Desktop
    4
    7
    2426
    Loading More Posts
    • 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.
    • N
      NeedDeen last edited by

      Hi

      My plan was to subclass QWidget and to add a few get and set methods. I use a QWidget in combination with a QPlainTextEdit to read from files and show the content.

      The tool creates a new (empty !) tab, when you click on the fileview. It checks, if there is already the same tab, otherwise it creates a new one. But the problem is, when I click a second file in the fileview, the program crashes.

      @
      #include <QFile>
      #include <QFileInfo>
      #include <QFileSystemModel>
      #include <QDir>
      #include <QTreeView>
      #include <QDebug>

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      #include "FileWidget.h"

      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
      {
      setupUi(this);

      // Create file explorer
      modelFileExplorer = new QFileSystemModel;
      treeView->setModel(modelFileExplorer);
      modelFileExplorer->setRootPath(QDir::currentPath());
      treeView->setRootIndex(modelFileExplorer->index(QDir::currentPath()));
      }

      MainWindow::~MainWindow()
      {
      }

      void MainWindow::createFileWidget(QFile *file)
      {
      // Check if the new file widget already exists
      QString *newFileTitle = new QString(file->fileName()); // New file widget title as QString
      FileWidget *currentFileWidget;
      QString *currentFileWidgetTitle;
      for(int index = 0; index < tabWidget->count(); index++)
      {
      currentFileWidget = new FileWidget(listFileWidget.at(index)); // Get the widget in the list
      currentFileWidgetTitle = new QString(currentFileWidget->getFileWidgetTitle()); // And now get the title of this widget ------> HERE IS THE CRASH
      if(newFileTitle->compare(currentFileWidgetTitle) == 0)
      {
      tabWidget->setCurrentIndex(index); // Instead of creating a clone we just focus the current index
      return;
      }
      }

      // This file doesn't exist - we crreate a file widget
      FileWidget *widget = new FileWidget();
      QString *title = new QString(file->fileName());
      widget->setFileWidgetTitle(title);

      // Now we return this string and use it as tab title (For testing)
      QString *widgetTitle = new QString(widget->getFileWidgetTitle());
      tabWidget->addTab(widget, *widgetTitle);
      listFileWidget.append(widget);
      }

      void MainWindow::on_treeView_clicked(const QModelIndex &index)
      {
      QFile *file = new QFile(modelFileExplorer->fileInfo(index).absoluteFilePath());
      QFileInfo *fileInfo = new QFileInfo(*file);
      if(fileInfo->isFile())
      {
      createFileWidget(file);
      }
      }
      @

      @
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H

      #include <QMainWindow>
      #include <QFileSystemModel>
      #include <QList>

      #include "ui_mainwindow.h"
      #include "FileWidget.h"

      class MainWindow : public QMainWindow, Ui_MainWindow
      {
      Q_OBJECT

      public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();

      private slots:

      void on_treeView_clicked(const QModelIndex &index);

      private:
      Ui::MainWindow *ui;
      void createFileWidget(QFile *file);
      QFileSystemModel *modelFileExplorer;

      QList<FileWidget *> listFileWidget;
      };

      #endif // MAINWINDOW_H
      @

      Now the subclassed QWidget:

      @
      #include "FileWidget.h"

      FileWidget::FileWidget(QWidget *parent) : QWidget(parent)
      {
      textEditor = new QPlainTextEdit();
      QGridLayout *layout = new QGridLayout(this);
      layout->addWidget(textEditor, 0, 0, 1, 1);
      layout->setContentsMargins(0, 0, 0, 0);
      }

      void FileWidget::setFileWidgetTitle(QString *title)
      {
      projectFile = title;
      }

      QString FileWidget::getFileWidgetTitle()
      {
      return *projectFile;
      }
      @

      @#ifndef FILEWIDGET_H
      #define FILEWIDGET_H

      #include <QWidget>
      #include <QGridLayout>
      #include <QPlainTextEdit>
      #include <QString>
      #include <QFile>

      class FileWidget : public QWidget
      {
      Q_OBJECT

      public:
      FileWidget(QWidget *parent = 0);
      void setFileWidgetTitle(QString *title);
      QString getFileWidgetTitle();

      private:
      QString *projectFile;
      QPlainTextEdit *textEditor;
      };

      #endif // FILEWIDGET_H@

      Output:
      Starting C:...\TestWidget\TestWidget-build-Desktop-Debug\debug\TestWidget.exe...
      The program has unexpectedly finished.
      C:...\TestWidget\TestWidget-build-Desktop-Debug\debug\TestWidget.exe exited with code -1073741819

      1 Reply Last reply Reply Quote 0
      • P
        poor_robert last edited by

        Hmm, try to compile Your application with debug options.
        If You use QtCreator it has very nice Debugger interface and it will help You to locate place where program crashes. Of course You can use old good gdb :).

        1 Reply Last reply Reply Quote 0
        • G
          giesbert last edited by

          Hi,

          some comments:

          why do you create a QString on the stack? QString is an implicitly shared class, create it on the heap or as real member of the class and assign them directly. The way you use it creates at least one memory leak.

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply Reply Quote 0
          • G
            giesbert last edited by

            Hi,

            I tried oput your code.
            you do not initialise any variables and access them directly. This leads to the crash when opening the second file:

            @
            void MainWindow::createFileWidget(QFile *file)
            {
            // Check if the new file widget already exists
            QString *newFileTitle = new QString(file->fileName()); // New file widget title as QString
            FileWidget *currentFileWidget; /// <<-- uninitialiszed!
            QString *currentFileWidgetTitle;
            for(int index = 0; index < tabWidget->count(); index++)
            {
            // here you create a new widget with unititialized pointers!
            currentFileWidget = new FileWidget(listFileWidget.at(index)); // Get the widget in the list
            currentFileWidgetTitle = new QString(currentFileWidget->getFileWidgetTitle()); // And now get the title of this widget ------> HERE IS THE CRASH
            >// here you access the pointer!
            // .......
            }
            @

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply Reply Quote 0
            • T
              terenty last edited by

              Hi! Gerolf,
              bq. why do you create a QString on the stack? QString is an implicitly shared class, create it on the heap or as real member of the class and assign them directly. The way you use it creates at least one memory leak.

              Do you mean that
              @QString *newFileTitle = new QString(file->fileName());@
              is a bad way of creating Qstring and
              @QString newFileTitle(file->fileName());@

              is the right way?

              P.S. sorry cant understand how quotting works here

              1 Reply Last reply Reply Quote 0
              • N
                NeedDeen last edited by

                Thank you Gerold. Now I see my mistake, maybe I should check my basics skills in C++. Problem is now solved.

                @poor_robert At the moment I am under windows, I use gdb under linux but I cannot access a linux machine now

                1 Reply Last reply Reply Quote 0
                • G
                  giesbert last edited by

                  Hi NeedDeen,

                  fine that I could help. By the way: Windows compilers also know debug options. MSVC, Creator, whatever.. :-)

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post