hollowhead
12th February 2010, 14:17
These forums look very good, its nice to have a beginners section. I've been using the official QT4 gui programming book and the spreadsheet example therein to teach myself both to use the QT designer, api and C++ having only programmed in C up until now and then a few years ago. I built an SDI spreadsheet with some functionality. I decided I want it to be MDI so used the MDIeditor example in the book to do this. The program compiles but doesn't run it crashes. I've managed to alter a few things and get an empty window up.
The gdb output is
Program received signal SIGSEGV, Segmentation fault.
0x00be5cb1 in QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
using back trace I get
#0 0x00be5cb1 in QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
#1 0x00be62d3 in QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) () from /usr/lib/libQtGui.so.4
#2 0x00fce52e in QMdiSubWindow::QMdiSubWindow(QWidget*, QFlags<Qt::WindowType>) () from /usr/lib/libQtGui.so.4
#3 0x00fc2acf in QMdiArea::addSubWindow(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
#4 0x08050f0a in MainWindowImpl::addSpreadsheet (this=0xbffff330,
spreadsheet=0x8196398) at src/mainwindowimpl.cpp:104
#5 0x08050cb5 in MainWindowImpl::newFile (this=0xbffff330)
at src/mainwindowimpl.cpp:51
#6 0x08050e5b in MainWindowImpl::loadFiles (this=0xbffff330)
at src/mainwindowimpl.cpp:85
#7 0x0805e0c5 in MainWindowImpl::qt_metacall (this=0xbffff330,
_c=QMetaObject::InvokeMetaMethod, _id=4, _a=0xbfffebcc)
at build/moc_mainwindowimpl.cpp:89
#8 0x00964263 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/libQtCore.so.4
#9 0x00964ec2 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4
#10 0x00969387 in ?? () from /usr/lib/libQtCore.so.4
#11 0x0096949c in ?? () from /usr/lib/libQtCore.so.4
I'm stuck I've reduced the errors from more than above by correcting some errors in my signals and slots I don't seem to have left anything out but I must be missing something.... Can anyone help. I reluctant to post the code since there is a lot of it, had to leave out spreadsheet.cpp and .h due to posting limits though the errors seem to be in the mainwindow code. I've put the linenumbers in the code below, these don't match simply since I've taken blank lines out to save space. I feel like an idiot but need help would really appreciate a simple explanation of what is wrong so I can learn from the experience. Thanks
MainWindowImpl.h
Q_OBJECT
public:
MainWindowImpl( QWidget * parent = 0, Qt::WFlags f = 0 );
public slots:
void printPreview();
void newFile();
void openFile(const QString &fileName);
private slots:
void updateActions(); // added 11/2/09 for MDI
void loadFiles();// added 11/2/09 for MDI
void copy();
void paste();
void cut();
void selectAll();
void selectCurrentColumn();
void selectCurrentRow();
void selectFont();
void goToCell();
private:
void createActionGroup();
QMdiArea *mdiArea;
void createContextMenu();
void addSpreadsheet(Spreadsheet *spreadsheet); // added 11/2/09 for MDI
Spreadsheet *activeSpreadsheet(); // added 11/2/09 for MDI
QMenu *windowMenu;
//Spreadsheet *spreadsheet; // default constructor removed for MDI
QActionGroup *windowActionGroup;
QAction *closeAction;
QAction *closeAllAction;
QAction *tileAction;
QAction *cascadeAction;
QAction *nextAction;
QAction *previousAction;
};
#endif
MainWindowImpl.cpp
#include <QtGui>
#include "mainwindowimpl.h"
#include "spreadsheet.h" // required for most menu functions
#include "GoToCellDialog.h"
#include "printview.h"
//
MainWindowImpl::MainWindowImpl(QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
//setAttribute(Qt::WA_DeleteOnClose); // frees memory from MDI windows
//spreadsheet = new Spreadsheet; commented out for MDI 11/2/10
mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
setupUi(this);
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
this, SLOT(updateActions()));
createActionGroup();
QTimer::singleShot(0, this, SLOT(loadFiles()));
//setCentralWidget(spreadsheet); // centre spreadsheet on form between statusbar, toolbar and
//createContextMenu();
// setup signals and slots for menu actions starting with basic ones
connect(actionC_opy_Ctrl_C, SIGNAL(triggered()), this, SLOT(copy()));
connect(actionSelect_All_Ctrl_A, SIGNAL(triggered()), this, SLOT(selectAll()));
connect(actionSelect_Co_lumn, SIGNAL(triggered()), this, SLOT(selectCurrentColumn()));
connect(actionSelect_Ro_w, SIGNAL(triggered()),this, SLOT(selectCurrentRow()));
connect(action_Paste_Ctrl_V, SIGNAL(triggered()), this, SLOT(paste()));
connect(action_Cut_Ctrl_X, SIGNAL(triggered()), this, SLOT(cut()));
connect(actionFont, SIGNAL(triggered()), this, SLOT(selectFont()));
connect(actionGoto_Cell, SIGNAL(triggered()),this, SLOT(goToCell()));
connect(actionPrint_Pre_view_Alt_P, SIGNAL(triggered()), this, SLOT(printPreview()));
//connect(actionShow_Grid_Alt_G, SIGNAL(toggled(bool)), this, SLOT(setShowGrid(bool)));
//connect(actionPrint_S_elected_Range, SIGNAL(triggered()), this, SLOT(toHtml(const QString &plainText)));
//connect(actionPrint_S_elected_Range, SIGNAL(triggered()), this, SLOT(printHtml(const QString &html)));
connect(action_New_Ctrl_N, SIGNAL(triggered()),this, SLOT(newFile()));
}
//
void MainWindowImpl::newFile()
{
Spreadsheet *spreadsheet = new Spreadsheet;
spreadsheet->newFile();
addSpreadsheet(spreadsheet); // line 51
}
void MainWindowImpl::updateActions()
{
/* bool hasSpreadsheet = (activeSpreadsheet() != 0);
bool hasSelection = activeSpreadsheet()
&& activeSpreadsheet()->textCursor().hasSelection();*/
/* saveAction->setEnabled(hasEditor);
saveAsAction->setEnabled(hasEditor);
cutAction->setEnabled(hasSelection);
copyAction->setEnabled(hasSelection);
pasteAction->setEnabled(hasEditor);
closeAction->setEnabled(hasEditor);
closeAllAction->setEnabled(hasEditor);
tileAction->setEnabled(hasEditor);
cascadeAction->setEnabled(hasEditor);
nextAction->setEnabled(hasEditor);
previousAction->setEnabled(hasEditor);
separatorAction->setVisible(hasEditor); */
if (activeSpreadsheet())
activeSpreadsheet()->windowMenuAction()->setChecked(true);
}
void MainWindowImpl::loadFiles() // added 11/2/09 for MDI
{
QStringList args = QApplication::arguments();
args.removeFirst();
if (!args.isEmpty()) {
foreach (QString arg, args)
openFile(arg);
mdiArea->cascadeSubWindows();
} else {
newFile(); //line 85 line 89 is case 4: loadFiles(); break; in moc file
}
mdiArea->activateNextSubWindow();
}
void MainWindowImpl::openFile(const QString &fileName) // added 11/2/09 for MDI
{
Spreadsheet *spreadsheet = Spreadsheet::openFile(fileName, this);
if (spreadsheet)
addSpreadsheet(spreadsheet);
}
void MainWindowImpl::addSpreadsheet(Spreadsheet *spreadsheet) // added 11/2/09 for MDI
{
QMdiSubWindow *subWindow = mdiArea->addSubWindow(spreadsheet); // line 104
windowMenu->addAction(spreadsheet->windowMenuAction());
windowActionGroup->addAction(spreadsheet->windowMenuAction());
subWindow->show();
}
Spreadsheet *MainWindowImpl::activeSpreadsheet() // added 11/2/09 for MDI
{
QMdiSubWindow *subWindow = mdiArea->activeSubWindow();
if (subWindow)
return qobject_cast<Spreadsheet *>(subWindow->widget());
return 0;
}
void MainWindowImpl::createActionGroup()
{
windowActionGroup = new QActionGroup(this);
}
/*
void MainWindowImpl::createContextMenu()
{
activeSpreadsheet()->addAction(action_Cut_Ctrl_X);//changed from spreadsheet() for MDI
activeSpreadsheet()->addAction(actionC_opy_Ctrl_C);//changed from spreadsheet() for MDI
activeSpreadsheet()->addAction(action_Paste_Ctrl_V);//changed from spreadsheet() for MDI
activeSpreadsheet()->setContextMenuPolicy(Qt::ActionsContextMenu);//changed from spreadsheet() for MDI
}
*/
void MainWindowImpl::goToCell()
{
GoToCellDialog dialog(this);
if (dialog.exec())
{
QString str = dialog.lineEdit->text().toUpper();
activeSpreadsheet()->setCurrentCell(str.mid(1).toInt() - 1, //changed from spreadsheet() for MDI
str[0].unicode() - 'A');
}
}
void MainWindowImpl::printPreview()
{
#ifndef QT_NO_PRINTER
QPrinter printer(QPrinter::ScreenResolution); // set printer to screen resolution
QPrintPreviewDialog dlg(&printer);
PrintView view;
view.setModel(activeSpreadsheet()->model()); //changed from spreadsheet() for MDI
connect(&dlg, SIGNAL(paintRequested(QPrinter *)),
&view, SLOT(print(QPrinter *)));
dlg.exec();
#endif
}
void MainWindowImpl::copy()
{
if (activeSpreadsheet())
activeSpreadsheet()->copy();
}
void MainWindowImpl::paste()
{
if (activeSpreadsheet())
activeSpreadsheet()->paste();
}
void MainWindowImpl::cut()
{
if (activeSpreadsheet())
activeSpreadsheet()->cut();
}
void MainWindowImpl::selectAll()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectAll();
}
void MainWindowImpl::selectCurrentColumn()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectCurrentColumn();
}
void MainWindowImpl::selectCurrentRow()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectCurrentRow();
}
The gdb output is
Program received signal SIGSEGV, Segmentation fault.
0x00be5cb1 in QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
using back trace I get
#0 0x00be5cb1 in QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
#1 0x00be62d3 in QWidget::QWidget(QWidgetPrivate&, QWidget*, QFlags<Qt::WindowType>) () from /usr/lib/libQtGui.so.4
#2 0x00fce52e in QMdiSubWindow::QMdiSubWindow(QWidget*, QFlags<Qt::WindowType>) () from /usr/lib/libQtGui.so.4
#3 0x00fc2acf in QMdiArea::addSubWindow(QWidget*, QFlags<Qt::WindowType>) ()
from /usr/lib/libQtGui.so.4
#4 0x08050f0a in MainWindowImpl::addSpreadsheet (this=0xbffff330,
spreadsheet=0x8196398) at src/mainwindowimpl.cpp:104
#5 0x08050cb5 in MainWindowImpl::newFile (this=0xbffff330)
at src/mainwindowimpl.cpp:51
#6 0x08050e5b in MainWindowImpl::loadFiles (this=0xbffff330)
at src/mainwindowimpl.cpp:85
#7 0x0805e0c5 in MainWindowImpl::qt_metacall (this=0xbffff330,
_c=QMetaObject::InvokeMetaMethod, _id=4, _a=0xbfffebcc)
at build/moc_mainwindowimpl.cpp:89
#8 0x00964263 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/libQtCore.so.4
#9 0x00964ec2 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4
#10 0x00969387 in ?? () from /usr/lib/libQtCore.so.4
#11 0x0096949c in ?? () from /usr/lib/libQtCore.so.4
I'm stuck I've reduced the errors from more than above by correcting some errors in my signals and slots I don't seem to have left anything out but I must be missing something.... Can anyone help. I reluctant to post the code since there is a lot of it, had to leave out spreadsheet.cpp and .h due to posting limits though the errors seem to be in the mainwindow code. I've put the linenumbers in the code below, these don't match simply since I've taken blank lines out to save space. I feel like an idiot but need help would really appreciate a simple explanation of what is wrong so I can learn from the experience. Thanks
MainWindowImpl.h
Q_OBJECT
public:
MainWindowImpl( QWidget * parent = 0, Qt::WFlags f = 0 );
public slots:
void printPreview();
void newFile();
void openFile(const QString &fileName);
private slots:
void updateActions(); // added 11/2/09 for MDI
void loadFiles();// added 11/2/09 for MDI
void copy();
void paste();
void cut();
void selectAll();
void selectCurrentColumn();
void selectCurrentRow();
void selectFont();
void goToCell();
private:
void createActionGroup();
QMdiArea *mdiArea;
void createContextMenu();
void addSpreadsheet(Spreadsheet *spreadsheet); // added 11/2/09 for MDI
Spreadsheet *activeSpreadsheet(); // added 11/2/09 for MDI
QMenu *windowMenu;
//Spreadsheet *spreadsheet; // default constructor removed for MDI
QActionGroup *windowActionGroup;
QAction *closeAction;
QAction *closeAllAction;
QAction *tileAction;
QAction *cascadeAction;
QAction *nextAction;
QAction *previousAction;
};
#endif
MainWindowImpl.cpp
#include <QtGui>
#include "mainwindowimpl.h"
#include "spreadsheet.h" // required for most menu functions
#include "GoToCellDialog.h"
#include "printview.h"
//
MainWindowImpl::MainWindowImpl(QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
//setAttribute(Qt::WA_DeleteOnClose); // frees memory from MDI windows
//spreadsheet = new Spreadsheet; commented out for MDI 11/2/10
mdiArea = new QMdiArea;
setCentralWidget(mdiArea);
setupUi(this);
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
this, SLOT(updateActions()));
createActionGroup();
QTimer::singleShot(0, this, SLOT(loadFiles()));
//setCentralWidget(spreadsheet); // centre spreadsheet on form between statusbar, toolbar and
//createContextMenu();
// setup signals and slots for menu actions starting with basic ones
connect(actionC_opy_Ctrl_C, SIGNAL(triggered()), this, SLOT(copy()));
connect(actionSelect_All_Ctrl_A, SIGNAL(triggered()), this, SLOT(selectAll()));
connect(actionSelect_Co_lumn, SIGNAL(triggered()), this, SLOT(selectCurrentColumn()));
connect(actionSelect_Ro_w, SIGNAL(triggered()),this, SLOT(selectCurrentRow()));
connect(action_Paste_Ctrl_V, SIGNAL(triggered()), this, SLOT(paste()));
connect(action_Cut_Ctrl_X, SIGNAL(triggered()), this, SLOT(cut()));
connect(actionFont, SIGNAL(triggered()), this, SLOT(selectFont()));
connect(actionGoto_Cell, SIGNAL(triggered()),this, SLOT(goToCell()));
connect(actionPrint_Pre_view_Alt_P, SIGNAL(triggered()), this, SLOT(printPreview()));
//connect(actionShow_Grid_Alt_G, SIGNAL(toggled(bool)), this, SLOT(setShowGrid(bool)));
//connect(actionPrint_S_elected_Range, SIGNAL(triggered()), this, SLOT(toHtml(const QString &plainText)));
//connect(actionPrint_S_elected_Range, SIGNAL(triggered()), this, SLOT(printHtml(const QString &html)));
connect(action_New_Ctrl_N, SIGNAL(triggered()),this, SLOT(newFile()));
}
//
void MainWindowImpl::newFile()
{
Spreadsheet *spreadsheet = new Spreadsheet;
spreadsheet->newFile();
addSpreadsheet(spreadsheet); // line 51
}
void MainWindowImpl::updateActions()
{
/* bool hasSpreadsheet = (activeSpreadsheet() != 0);
bool hasSelection = activeSpreadsheet()
&& activeSpreadsheet()->textCursor().hasSelection();*/
/* saveAction->setEnabled(hasEditor);
saveAsAction->setEnabled(hasEditor);
cutAction->setEnabled(hasSelection);
copyAction->setEnabled(hasSelection);
pasteAction->setEnabled(hasEditor);
closeAction->setEnabled(hasEditor);
closeAllAction->setEnabled(hasEditor);
tileAction->setEnabled(hasEditor);
cascadeAction->setEnabled(hasEditor);
nextAction->setEnabled(hasEditor);
previousAction->setEnabled(hasEditor);
separatorAction->setVisible(hasEditor); */
if (activeSpreadsheet())
activeSpreadsheet()->windowMenuAction()->setChecked(true);
}
void MainWindowImpl::loadFiles() // added 11/2/09 for MDI
{
QStringList args = QApplication::arguments();
args.removeFirst();
if (!args.isEmpty()) {
foreach (QString arg, args)
openFile(arg);
mdiArea->cascadeSubWindows();
} else {
newFile(); //line 85 line 89 is case 4: loadFiles(); break; in moc file
}
mdiArea->activateNextSubWindow();
}
void MainWindowImpl::openFile(const QString &fileName) // added 11/2/09 for MDI
{
Spreadsheet *spreadsheet = Spreadsheet::openFile(fileName, this);
if (spreadsheet)
addSpreadsheet(spreadsheet);
}
void MainWindowImpl::addSpreadsheet(Spreadsheet *spreadsheet) // added 11/2/09 for MDI
{
QMdiSubWindow *subWindow = mdiArea->addSubWindow(spreadsheet); // line 104
windowMenu->addAction(spreadsheet->windowMenuAction());
windowActionGroup->addAction(spreadsheet->windowMenuAction());
subWindow->show();
}
Spreadsheet *MainWindowImpl::activeSpreadsheet() // added 11/2/09 for MDI
{
QMdiSubWindow *subWindow = mdiArea->activeSubWindow();
if (subWindow)
return qobject_cast<Spreadsheet *>(subWindow->widget());
return 0;
}
void MainWindowImpl::createActionGroup()
{
windowActionGroup = new QActionGroup(this);
}
/*
void MainWindowImpl::createContextMenu()
{
activeSpreadsheet()->addAction(action_Cut_Ctrl_X);//changed from spreadsheet() for MDI
activeSpreadsheet()->addAction(actionC_opy_Ctrl_C);//changed from spreadsheet() for MDI
activeSpreadsheet()->addAction(action_Paste_Ctrl_V);//changed from spreadsheet() for MDI
activeSpreadsheet()->setContextMenuPolicy(Qt::ActionsContextMenu);//changed from spreadsheet() for MDI
}
*/
void MainWindowImpl::goToCell()
{
GoToCellDialog dialog(this);
if (dialog.exec())
{
QString str = dialog.lineEdit->text().toUpper();
activeSpreadsheet()->setCurrentCell(str.mid(1).toInt() - 1, //changed from spreadsheet() for MDI
str[0].unicode() - 'A');
}
}
void MainWindowImpl::printPreview()
{
#ifndef QT_NO_PRINTER
QPrinter printer(QPrinter::ScreenResolution); // set printer to screen resolution
QPrintPreviewDialog dlg(&printer);
PrintView view;
view.setModel(activeSpreadsheet()->model()); //changed from spreadsheet() for MDI
connect(&dlg, SIGNAL(paintRequested(QPrinter *)),
&view, SLOT(print(QPrinter *)));
dlg.exec();
#endif
}
void MainWindowImpl::copy()
{
if (activeSpreadsheet())
activeSpreadsheet()->copy();
}
void MainWindowImpl::paste()
{
if (activeSpreadsheet())
activeSpreadsheet()->paste();
}
void MainWindowImpl::cut()
{
if (activeSpreadsheet())
activeSpreadsheet()->cut();
}
void MainWindowImpl::selectAll()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectAll();
}
void MainWindowImpl::selectCurrentColumn()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectCurrentColumn();
}
void MainWindowImpl::selectCurrentRow()
{
if (activeSpreadsheet())
activeSpreadsheet()->selectCurrentRow();
}