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



  • 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



  • 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 :).



  • 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.



  • 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!
    // .......
    }
    @



  • 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



  • 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



  • Hi NeedDeen,

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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.