Segmentation fault in Qt application framework - qt

this generates a segmentation fault becuase of "QColor colorMap[9]";. If I remove colorMap the segmentation fault goes away. If I put it back. It comes back. If I do a clean all then build all, it goes away. If I increase its arraysize it comes back. On the other hand if I reduce it it doesnt come back. I tired adding this array to another project and
What could be happening. I am really curious to know. I have removed everything else in that class. This widget subclassed is used to promote a widget in a QMainWindow.
class LevelIndicator : public QWidget
{
public:
LevelIndicator(QWidget * parent);
void paintEvent(QPaintEvent * event );
float percent;
QColor colorMap[9];
int NUM_GRADS;
};
the error happens inside ui_mainwindow.h at one of these lines:
hpaFwdPwrLvl->setObjectName(QString::fromUtf8("hpaFwdPwrLvl"));
verticalLayout->addWidget(hpaFwdPwrLvl);
I know i am not providing much but I will give alink to the app. Im trying to see if anyone has a quick answer for this.

If I do a clean all then build all, it goes away.
This makes it sound as though your build system isn't recognizing a dependency and that a change to that class definition isn't triggering a rebuild of something that should be recompiled when the definition changes.
Make sure class LevelIndicator is defined in exactly one place (generally that would be a header file that gets included by whatever modules need to use a LevelIndicator object). Also make sure that any global/static instances of LevelIndicator objects are following the one definition rule.

Firstly it might not be QColor, that may simply be changing the memory layout enough that a buffer overrun somewhere else triggers a segfault - try a different size QColor ..[1] for example.
Can QColor be used as an array like this, does it have the correct default ctor?

Related

Application GUI state saving in Qt

What is an optimal and an appropriate way to save the state of a Qt GUI so I get the same state I had back when I closed the application ?
By state I mean : current indexes (for combo box ...), color palette, widgets positions... right before closing the application
You can use the QSettings class.
Simple use of QSettings class (code inspired from Qt's documentation):
In the main-window of your application code member functions that saves and restore the settings:
void MainWindow::writeSettings()
{
QSettings settings("reaffer Soft", "reafferApp");
settings.beginGroup("MainWindow");
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.endGroup();
}
void MainWindow::readSettings()
{
QSettings settings("reaffer Soft", "reafferApp");
settings.beginGroup("MainWindow");
resize(settings.value("size", QSize(400, 400)).toSize());
move(settings.value("pos", QPoint(200, 200)).toPoint());
settings.endGroup();
}
Call those 2 functions from the MainWindow constructor and from the closeEvent override, like this:
MainWindow::MainWindow()
{
// code from constructor
//...
readSettings();
}
void MainWindow::closeEvent(QCloseEvent *event)
{
//optional check if the user really want to quit
// and/or if the user want to save settings
writeSettings();
event->accept();
}
The direct answer requires specific elaborated design for your code and not really a short Qt question or even the question specific to Qt. That is about C++ which is not the VM-based language that assists with serializing the state of program code to data. Having all objects serializable we can then attempt to apply certain C++/Qt classes/techniques.
This task is much easier to accomplish with languages like Java, though. And with C++/Qt you have to routinely make serialize-able / serialize / restore everything that is running in your code and still no guarantee that works as long as the context is not fully captured. This task is not easy for sure and makes sense only in specific application.
The most you can get directly from Qt is to save/restore QMainWindow and other independent widgets geometry (position/size):
saveGeometry
restoreGeometry
... and that solution is still somewhat incomplete or you may/not use QSettings for the storage.
I use QSettings for this. With routines similar to Zlatomir's.
For each window I have in the project I use a different section in QSettings and have readSettings() and writeSettings() in the source for each window.
Anything on the form that I want to persist I have to explicitly save and recall. In the case of a QComboBox it would be something like:
QSettings settings("Organisation", "MySoftware");
settings.beginGroup("WindowNumberTwo");
settings.setValue("ComboIndex", combobox->currentIndex());
// save more values here
// ...
settings.endGroup();
I don't know of a built in way to persist your window states - it has to be don't value by value.

crash after QGraphicsProxyWidget is removed from a scene

I have a simple scene with a QGraphicsProxyWidget added to it ( and some widget set on it ).
If I try removing it from the scene, like so:
if ( widget )
{
parentScene->removeItem( m_widget ); // m_widget is a QGraphicsProxyWidget
delete m_widget; // I also tried m_widget->deleteLater() here - same result
m_widget = NULL;
}
I get an instant crash - no descriptive callstack though that would tell me what's wrong ( some windows related calls in the callstack, and that's all ).
I'm using version 5.1.1 of the Qt library, I've searched the manual and the net for an instruction how to actually remove such a widget, and it's not documented at all, so I'm not sure if I'm doing something wrong there, or is there a bug in the library.
I'd appreciate any help.
Cheers,
Piotr
Check your if statement: It says widget when you probably meant m_widget. If widget is non-null and m_widget is null, your program will crash, since the calls to removeItem/delete will attempt to reference a null pointer.
I found the problem - seemingly unrelated call to 'prepareGeometryChange' was to blame here.
My widgets were changing size ( I didn't mention it, 'cause it seemed irrelevant at the time ). However I was calling the aforementioned method AFTER I made the change to the geometry, not before, as the manual instructs.
Apparently that method is very important in order to keep the scene's internal data in order, and due to my calling it incorrectly, it was leaving some invalid references to the deleted items.

In QTableView, What "signal" triggers the editing mode

I'm trying to write some Inherit class (Let's call it A) from QTableView, and hope to overwrite the slot
void edit ( const QModelIndex & index )
from QAbstractItemView. I know that this function can trigger editing mode, but here is my question: I hope that whenever editing mode are triggered by user in this class A, the program can go inside the overwritten slot A::edit.
However, it seems only when A::edit are directly called, the program can get in.
Since QTableView comes from QAbstractItemView, if the editing mode is triggered by other way(such as mouse double click), the program will run default QAbstractItemView::edit instead of A::edit.
I tried to connect the signal "activated", but apparently it's not the correct signal to trigger editing mode. Is there anyway to do something every time when an editor is triggered?
Also, I'd like to do something when the editing mode is ended by pressing Enter or ESC or mouse clicking on other place. The same situation happens at the slot
void editorDestroyed ( QObject * editor )
Can anyone help me to solve this problem?
I'll really appreciate it, thanks!
QAbstractItemView::edit(const QModelIndex& index) is not virtual, so that's why when you call it directly you get your subclass's behavior, but when existing code calls it they get they base class behavior. If that doesn't ring a bell, read that link; Qt has a lot of virtual and non-virtual functions and knowing what the difference is will save you a lot of headaches.
However, QAbstractItemView::edit(const QModelIndex& index, EditTrigger trigger, QEvent* event) is virtual, so you can override it. I haven't verified it, but presumably the non-virtual edit() calls this edit(), so it should have the same effect.
QAbstractItemView::editorDestroyed(QObject* editor) is also virtual, so I'm not sure why it isn't be working. However, there is also QAbstractItemView::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint) which is also virtual, so you might want to try reimplementing that in your subclass. The closeEditor() documentation also suggests commitData(), which is also virtual. The Qt item views have a lot of similar methods, so don't assume that the first one you see is going to do exactly what you want/expect.
FYI, in case your not used to reimplementing virtual methods in a subclass, the fastest/easiest way to make sure your implementation is being called is to do something like:
class A : public QTableView {
void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) {
qDebug("my closeEditor was called!");
// call the real implementation so that the base class continues to work properly
QTableView::closeEditor(editor, hint);
}
};
You could do this with edit(), editorDestroyed(), closeEditor(), and commitData() to see which ones are called when.

CFileDialog as child of QWidget

Yes, I know, one should not mix different platforms, but I am working on a Qt application and now we have a new requirement: a standard Windows Open File Dialog should be used in place of a QFileDialog.
So I would like to create a CFileDialog that is a child of a QWidget. I have found a question related to the inverse problem: QWidget as a child of an existing MFC component but nothing about my specific issue.
My plan is to write a wrapper class
class FileStdWDialog : CFileDialog
with a constructor
FileDirStdWDialog(QWidget *parent, ...);
and map this to a call to the superclass constructor
CFileDialog(..., ..., ..., ..., ..., CWnd* pParentWnd, ...)
So, if I understand correctly, my problem boils down to mapping
a QWidget * to a CWnd *. Do you know if there is an easy way to do this?
Update
Thanks for the hints. Probably, getting the HWND for a QWidget and
converting this to CWnd * is the right solution. I will try this way.
You could call ::GetOpenFileName and ::GetSaveFileName. Those are the Win32 functions that CFileDialog wraps, I think. So you wouldn't need MFC.
By the way, starting with Windows Vista, it is recommended to use the Common Item Dialog, rather than the standard Open and Save dialogs.

QPlainTextEdit segmentation fault

I have some Qt application with QPlainTextEdit in Tab widget. When try to make a pointer on it
QPlainTextEdit *w = (QPlainTextEdit*)ui->tabWidget->widget(0)
and call a document() method
w->document()
I get a segfault.
But if i call document directly, e.g. ui->mainEdit->document(), then everything works fine.
Can anybody explain me why it happens?
You want to do:
QPlainTextEdit *w = ui->mainEdit;
Then w->document() will return what you want. You are getting the segmentation fault because when you cast ui->tabWidget->widget(0); gives a pointer to a tab page object. When you cast this to QPlainTextEdit* are telling your program to treat a part of memory that does not represent a QPlainTextEdit as a QPlainTextEdit. This causes trouble at the time that you call w->document() because that is in the memory location that it tries to access is not what it would expect from memory which belongs to QPlainTextEdit.
i'm almost sure, that ui->tabWidget->widget(0) return container widget inside of tabWidget. Try qDebug() << ui->tabWidget->widget(0)->metaObject()->className() and see what is printed. It's probably just "QWidget" not "QPlainTextEdit". Your edit is inside of layout of this widget
You can use qobject_cast to make sure that it returns the right type.
QPlainTextEdit *w = qobject_cast<QPlainTextEdit*>(ui->tabWidget->widget(0));
if (w)
{
...
}
It'll return 0 if the type is not of QPlainTextEdit*.
As stated, widget(0) is probably not returning what you wanted - and probably contains a container or some other item, and is probably not the way you want to be accessing your widgets unless there is no other way.

Resources