[SOLVED] Call of a subclassed QWidget method crashes the program
-
wrote on 6 Dec 2012, 10:37 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_OBJECTpublic:
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_OBJECTpublic:
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 -
wrote on 6 Dec 2012, 11:09 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 :). -
wrote on 6 Dec 2012, 11:47 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.
-
wrote on 6 Dec 2012, 11:59 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!
// .......
}
@ -
wrote on 6 Dec 2012, 12:14 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
-
wrote on 6 Dec 2012, 12:27 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
-
wrote on 6 Dec 2012, 14:11 last edited by
Hi NeedDeen,
fine that I could help. By the way: Windows compilers also know debug options. MSVC, Creator, whatever.. :-)
1/7