Just recently I've installed the Qt libraries on my computer, and as a complete novice I looked up the Qt 4.7 Getting Started guides online.
Just on the first page they provide the following code:
1 #include <QtGui>
2
3 int main(int argv, char **args)
4 {
5 QApplication app(argv, args);
6
7 QTextEdit textEdit;
8 QPushButton quitButton("Quit");
9
10 QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
11
12 QVBoxLayout layout;
13 layout.addWidget(&textEdit);
14 layout.addWidget(&quitButton);
15
16 QWidget window;
17 window.setLayout(&layout);
18
19 window.show();
20
21 return app.exec();
22 }
Simple stuff, I would suppose. Upon writing this code in Visual Studio Express 2010, building, and running, most everything works. However, when I try to close the window by means of the "Quit" button or the red-x in the top right of the displayed window (initiating "return app.exec()"), I receive the following:
A dialog box saying,
Unhandled exception at 0x77bc15de in ParticleTracker.exe: 0xC0000005: Access violation reading location 0xdf94b4b4.
And console output saying,
Critical error detected c0000374
Windows has triggered a breakpoint in ParticleTracker.exe.
This may be due to a corruption of the heap, which indicates a bug in ParticleTracker.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while ParticleTracker.exe has focus.
Having entered the debug-mode, I continued through the call stack while repeatedly receiving heap corruption errors.
First-chance exception at 0x77c6e6c3 in ParticleTracker.exe: 0xC0000374: A heap has been corrupted.
Unhandled exception at 0x77bc15de in ParticleTracker.exe: 0xC0000374: A heap has been corrupted.
All of the subsequent exceptions occurred at 0x77bc15de in the executable, with the memory address 0xC0000374 as a corrupted heap.
Honestly, I'm not precisely sure how I could even be getting this issue; I'm not well-versed in C++, but there appears to be nothing wrong with the code.
In the Call-Stack, the process is currently stuck at:
ParticleTracker.exe!main(int argv, char** args) Line 20 + 0x27 bytes
If I enter the disassembly the process is stuck at:
return app.exec();
00FE3831 mov esi,esp
00FE3833 call dword ptr [__imp_QApplication::exec (0FE93D0h)]
00FE3839 cmp esi,esp
00FE383B call #ILT+320(__RTC_CheckEsp) (0FE1145h)
00FE3840 mov dword ptr [ebp-150h],eax
00FE3846 mov byte ptr [ebp-4],5
00FE384A mov esi,esp
00FE384C lea ecx,[ebp-84h]
00FE3852 call dword ptr [__imp_QWidget::~QWidget (0FE9404h)]
00FE3858 cmp esi,esp
Any tips? Much appreciated. :)
Try this one
#include <QtGui>
int main(int argv, char **args)
{
QApplication app(argv, args);
QTextEdit *textEdit = new QTextEdit();
QPushButton *quitButton = new QPushButton("Quit");
QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(textEdit);
layout->addWidget(quitButton);
QWidget *window = new QWidget();
window->setLayout(layout);
window->show();
return app.exec();
}
It might be about ownership. When a widget is destroyed, it also takes care of its children, in your case, layouts and child widgets. QWidget destructior tries to destruct the objects, but they were allocated on the stack, and not dynamically.
Try to use dynamic allocation for QLayouts and widgets.
Related
I am a new guy to Qt although I have been writing in C for many years only about a year or so using c++. We are writing a camera app which has some C++ code for accessing frame buffers, video, etc. and a GUI that is written in QML. It is necessary to invoke gstreamer in a c++ class which needs to run in a separate thread and needs to be invoked from the QML code (because the QML code hangs waiting for threads to finish if it is invoked before starting the QML).
I found what looked like a great way to do it in the answer to someone else's question: How Start a Qthread from qml?. Unfortunately when I attempted to modify my code to run as shown in one of the answers I am getting a SIGABT signal. This happens when the code executes the following line:
view.engine()->rootContext()->setContextProperty("thread", &gstworker);
The main.cpp function looks like this:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQmlContext>
#include <gst/gst.h>
#include "common.h"
#include "fbctl.h"
#include "gstcameraif.h"
#include "gstworker.h"
int main(int argc, char *argv[])
{
DBG_PRINT("main.cpp: register FbCtl type\n");
qmlRegisterType<FbCtl>("test.fbctl.qt", 1, 0, "FbCtl");
DBG_PRINT("main.cpp: register GstCameraIf type\n");
qmlRegisterType<GstCameraIf>("test.gstcameraif.qt", 1, 0, "GstCameraIf");
DBG_PRINT("main.cpp: register GstWorker type");
qmlRegisterType<GstWorker>("test.gstworker.qt", 1, 0, "GstWorker");
gst_init(&argc, &argv);
GstCameraIf gStreamer;
FbCtl fbSetup; // get a local instance of the frame buffer control object
fbSetup.setupOverlay(); // initialize the overlay setup
fbSetup.stopProcess(); // close opened descriptors, unmap frame buffers
qputenv("QT_QPA_EGLFS_FB", "dev/fb1"); // redirects QT to use fb1 (overlay) and gstreamer will go to fb0
GstWorker gstworker;
QQuickView view;
view.engine()->rootContext()->setContextProperty("thread", &gstworker);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
gst_deinit();
return app.exec();
}
The function call list (stack) shows the following trace:
1 __GI_raise raise.c 54 0xb5ae1910
2 __GI_abort abort.c 89 0xb5ae2ca0
3 qt_message_fatal qlogging.cpp 1687 0xb5e0fff8
4 QMessageLogger::fatal qlogging.cpp 795 0xb5e0fff8
5 qt_pixmap_thread_test qpixmap.cpp 74 0xb670ce98
6 QPixmap::QPixmap qpixmap.cpp 109 0xb670ce98
7 QCursorData::QCursorData qcursor.cpp 624 0xb66a3360
8 QCursorData::initialize qcursor.cpp 655 0xb66a3360
9 QCursor::QCursor qcursor.cpp 470 0xb66a3360
10 QWindowPrivate::QWindowPrivate qwindow_p.h 107 0xb6bb3a78
11 QQuickWindowPrivate::QQuickWindowPrivate qquickwindow.cpp 501 0xb6bb3a78
12 QQuickViewPrivate::QQuickViewPrivate qquickview.cpp 77 0xb6c306e0
13 QQuickView::QQuickView qquickview.cpp 166 0xb6c30778
14 main main.cpp 38 0x131c8
My question is what do I need to fix to get rid of the sigabt signal.
thanks for any help you can give.
When I got the error again I noticed that it was actually happening when I declared the QQuickView object. I changed the main.cpp to use the QQmlApplicationEngine (instead of creating a quickview engine) to set the context and the error no longer occurs.
FYI: The SIGABT error was given in a message box and that is all it said.
I would like to give credit to #m7913d for the help in solving this issue.
I have the following use case (doesn't really make sense, because it's minimized from a real-life working example, however I think it's still technically correct):
class Dialog : public QDialog
{
public:
Dialog(QWidget* parent)
: QDialog(parent)
{
new Q3ListView(this); // this will crash
// new QWidget(this); // this won't crash
}
};
Depending on what is added to the Dialog the program will crash or not when deleting the Dialog instance (as indicated by the comments in the snippet), but only when main window's flags have been modified. Here is the code for the MainWindow class, which uses Dialog:
class MainWindow : public QMainWindow
{
public:
// the fact that the widget (dialog) below
// has no chance to show seems irrelevant.
// In the real scenario I have, the widget is shown on
// the screen and is closed by the user.
// I've just put the whole sequence of pieces of code
// that result from signal/slot calls, that in turn
// result from a point&click scenario in our application
// into the following function for brevity.
void go()
{
auto dialog = new Dialog(this);
dialog->show();
dialog->close();
disableAlwaysOnTop();
delete dialog; // or dialog->deleteLater();
}
void disableAlwaysOnTop()
{
setAttribute(Qt::WA_Resized, true);
Qt::WindowFlags flags = windowFlags();
setWindowFlags(flags ^ (Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
setVisible(true);
}
};
and the implementation of main:
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
mainWindow.go();
return app.exec();
}
All lines seem essential to reproduce the crash.
Is it a bug in Qt, or am I doing something wrong?
Manually deleting widget's children is allowed, and they should automatically unregister from their parents as indicated in the quote from the manual below. In my real-life case the widget is deleted to disappear from the GUI, and it works in case of other widget combinations. As indicated in the comment above, changing delete dialog; to dialog->deleteLater(); doesn't help.
It seems that there is a problem in removing the Q3ListView instance from Qt's backing store, here is the stack trace:
QtGuid4.dll!QWidgetBackingStore::staticContents(QWidget * parent, const QRect & withinClipRect) Line 499 C++
QtGuid4.dll!QWidgetBackingStore::sync() Line 1200 C++
QtGuid4.dll!QWidgetPrivate::syncBackingStore() Line 1896 C++
QtGuid4.dll!QWidget::event(QEvent * event) Line 8694 C++
QtGuid4.dll!QMainWindow::event(QEvent * event) Line 1479 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4565 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 4530 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 955 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtCored4.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1579 C++
QtCored4.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 498 C++
[External Code]
QtCored4.dll!QEventDispatcherWin32::processEvents(QFlags flags) Line 823 C++
QtGuid4.dll!QGuiEventDispatcherWin32::processEvents(QFlags flags) Line 1216 C++
QtCored4.dll!QEventLoop::processEvents(QFlags flags) Line 150 C++
QtCored4.dll!QEventLoop::exec(QFlags flags) Line 204 C++
QtCored4.dll!QCoreApplication::exec() Line 1227 C++
QtGuid4.dll!QApplication::exec() Line 3824 C++
qt_bug.exe!main(int argc, char * * argv) Line 60 C++
And the piece of Qt's code that attempts to use a pointer to a deleted object in the line indicated in the stack trace:
for (int i = 0; i < count; ++i) {
QWidget *w = staticWidgets.at(i);
QWidgetPrivate *wd = w->d_func();
if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty() // ****
|| !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
continue;
}
(wd points to a deleted object at the line marked with the comment).
Disclaimer:
I know that more elegant solutions exist but this is legacy code, and according to Qt's manual:
You can also delete child objects yourself, and they will remove themselves from their parents.
this code is valid.
We've reproduced the problem on Windows 7 (MSVC 2010 SP1, CL 16), Windows 8 (MSVC 2013 U4, CL 18) and Fedora 20 (GCC 4.8.3).
I've filed a bug report. Since it concerns an old version of the library no hopes that it will be fixed.
We are successively removing Qt3Support anyway and so is everyone advised ;)
I'm trying to make drag and drop inside a tree widget work to be able to move items around inside that widget. I've managed to make items draggable but when I release the mouse button the item disappears. To narrow it down I've tried the following example (taken from another post here on SO) which has the same issues as my tree widget in Qt 5.4 on Windows 7:
#include <QListWidget>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QListWidget lw;
for(int i = 1; i < 10; ++i)
lw.addItem(new QListWidgetItem(QString("Item %1").arg(i)));
lw.setDragEnabled(true); // ***
lw.viewport()->setAcceptDrops(true); // ***
lw.setDefaultDropAction(Qt::MoveAction); // ***
lw.setDropIndicatorShown(true); // ***
lw.setDragDropMode(QAbstractItemView::InternalMove);
lw.show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
a.exec();
}
When I run this code and drag/drop some items it looks like this:
Why is the dragged item removed? Any ideas of what I'm missing?
I have changed one line in your code:
lw.setDefaultDropAction(Qt::TargetMoveAction);
and now it works fine (Qt 5.4.1 Windows 8, Visual Studio 2013).
It's a bug in Qt 5.4.1, your code work correctly on Qt 4.8.6
With Qt 5.10 or later, you have to call "setMovement(QListView::Free)"
myList->setDragDropMode(QAbstractItemView::InternalMove);
myList->setDefaultDropAction(Qt::TargetMoveAction);
#if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
myList->setMovement(QListView::Free);
#endif
My goal is to build a Game Boy emulator. In order to do this, I would like to embed an SDL2 surface into a wxWidgets window.
I found this tutorial: http://code.technoplaza.net/wx-sdl/part1/, but my program crashes as soon as I run it. However I suspect this was intended for SDL1.2. Part of the program is shown below.
It seems that if I call SDL_Init() and also attempt to show a wxFrame (which, in this case, is MainWindow), it shows the window for a second and then the program crashes. I commented all other calls to SDL in my program so far, so it seems the problem lies with calling Show() on a wxFrame and initing SDL2 in the same program.
So the question is: can SDL2 and wxWidgets 3 work together? If not, could you guys suggest to me good alternatives a GUI of a Game Boy emulator? Does wxWidgets have its own graphics frame like Qt does (I'd rather avoid Qt)?
Thanks very much!
#include "MainApp.h"
#include "MainWindow.h"
#include <stdexcept>
namespace GBEmu {
static void initSDL() {
//This and SDL_Quit() are the only calls to the SDL library in my code
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
throw std::runtime_error("Fatal Error: Could not init SDL");
}
}
bool MainApp::OnInit()
{
try {
//If I comment out this line, the MainWindow wxFrame shows up fine.
//If I leave both uncommented, the window shows up quickly and then
//crashes.
initSDL();
//If I comment out this line and leave initSDL() uncommented,
//the program will not crash, but just run forever.
(new MainWindow("GBEmu", {50,50}, {640,480}))->Show();
} catch(std::exception &e) {
wxLogMessage(_("Fatal Error: " + std::string(e.what())));
}
return true;
}
int MainApp::OnExit() {
SDL_Quit();
return wxApp::OnExit();
}
}
wxIMPLEMENT_APP(GBEmu::MainApp);
EDIT: Here is more information on how it crashes: It crashes with a Segfault in what seems to be the pthread_mutex_lock disassembly file. This is the output in the console with stack trace:
Starting /home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx...
The program has unexpectedly finished.
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx crashed
Stack trace:
Error: signal 11:
/home/dan/Documents/devStuff/GBEmuWx-build/GBEmuWx(_ZN5GBEmu7handlerEi+0x1c)[0x414805]
/lib/x86_64-linux-gnu/libc.so.6(+0x36ff0)[0x7fb88e136ff0]
/lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x30)[0x7fb88c12ffa0]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XrmQGetResource+0x3c)[0x7fb88d1ca15c]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XGetDefault+0xc2)[0x7fb88d1a7a92]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x94dcf)[0x7fb88af8edcf]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x97110)[0x7fb88af91110]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(cairo_surface_get_font_options+0x87)[0x7fb88af63e07]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2b61f)[0x7fb88af2561f]
/usr/lib/x86_64-linux-gnu/libcairo.so.2(+0x2ef95)[0x7fb88af28f95]
This is a screenshot of where it seems to fail (line 7):
Update: In my MainWindow class, I attach a menu bar to the window. However, it seems when I comment out the setting of the menu bar, the window will show up fine even with initing of SDL. The menu bar will show up fine if I have initSDL() commented out but not the setting of the menu bar. Here is where I set the menu bar:
MainWindow::MainWindow(const wxString &title, const wxPoint &pos, const wxSize &size)
:wxFrame(nullptr, wxIDs::MainWindow, title, pos, size){
wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_EXIT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
//commenting this line out will allow the window to showup
//and not crash the program
SetMenuBar(menuBar);
}
You are experiencing an old heisenbug.
The workaround is simple: you have to initialize SDL before wxWidgets (basically, before GTK). To achieve this, you have to change
wxIMPLEMENT_APP(GBEmu::MainApp);
to
wxIMPLEMENT_APP_NO_MAIN(GBEmu::MainApp);
so that wxWidgets doesn't hijack your main().
Then you have to create main() manually. In it, initialize SDL, then call wxEntry():
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cerr << "Could not initialize SDL.\n";
return 1;
}
return wxEntry(argc, argv);
}
More about the bug:
I have googled around a bit and found that this bug has come up in a few places over the years. There are open reports in many bug trackers that have stack traces very similar to the one you get here (with debug symbols).
The oldest report I could find is from 2005 (!!) from the cairo bug tracker (https://bugs.freedesktop.org/show_bug.cgi?id=4373).
My best guess is that the real hiding place of this bug in either in GTK, cairo, or X. Unfortunately I do not currently have the time to look into it more in depth.
The following application crashes on mainWindow->show();
#include <QApplication>
#include <QFrame>
#include <QPixmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Q_INIT_RESOURCE(resources);
QPixmap pix;
pix.load(":/resources/images/app/icon_glow.png");
QFrame *mainWindow = new QFrame;
mainWindow->setWindowIcon(QIcon(pix));
mainWindow->show();
return a.exec();
}
With the mainWindow->setWindowIcon(QIcon(pix)); commented out, everything works. Otherwise, the backtrace (SEGFAULT, trying to dereference 0x8; seems like a missing nullptr check somewhere) is:
0 ?? /usr/local/Qt32/5.3/gcc/plugins/platforms/libqxcb.so 0xf4991138
1 ?? /usr/local/Qt32/5.3/gcc/plugins/platforms/libqxcb.so 0xf4982d4c
2 ?? /usr/local/Qt32/5.3/gcc/plugins/platforms/libqxcb.so 0xf498e7e3
3 ?? /usr/local/Qt32/5.3/gcc/plugins/platforms/libqxcb.so 0xf498f0f4
4 QWindowPrivate::applyCursor() /usr/local/Qt32/5.3/gcc/lib/libQt5Gui.so.5 0xf7517942
5 QWindowPrivate::setCursor(QCursor const*) /usr/local/Qt32/5.3/gcc/lib/libQt5Gui.so.5 0xf75179f7
6 QWindow::setCursor(QCursor const&) /usr/local/Qt32/5.3/gcc/lib/libQt5Gui.so.5 0xf7517b16
7 ?? /usr/local/Qt32/5.3/gcc/lib/libQt5Widgets.so.5 0xf7ad5d65
8 QWidgetPrivate::show_sys() /usr/local/Qt32/5.3/gcc/lib/libQt5Widgets.so.5 0xf7ad60b6
9 QWidgetPrivate::show_helper() /usr/local/Qt32/5.3/gcc/lib/libQt5Widgets.so.5 0xf7abab35
10 QWidget::setVisible(bool) /usr/local/Qt32/5.3/gcc/lib/libQt5Widgets.so.5 0xf7abb005
11 QWidget::show() /usr/local/Qt32/5.3/gcc/lib/libQt5Widgets.so.5 0xf7aad77e
12 main main.cpp 17 0x804a21f
I tried loading the resource as follows:
QLabel *mainLabel = new QLabel;
mainLabel->setPixmap(pix);
mainLabel->show();
That works without a problem. Any help is greatly appreciated. Ubuntu 14.04 x64, compiled 32 bit, Qt 5.3
UPDATE: I reinstalled ubuntu-desktop (i reverted the desktop from 32 bit to 64 bit) and now I get an error:
The X11 connection broke: Maximum allowed requested length exceeded (code 4)
XIO: fatal IO error 2 (No such file or directory) on X server ":0"
after 409 requests (409 known processed) with 0 events remaining.
I have also encountered this. The reason is the icon is too large. Resize to something smaller, 256x256 for example.