After googling around I found out that segmentation faults are given when the program is pointed to use memory that it doesn’t have access to.
I’ve recently started experiencing these errors after I tried making a custom button class that would enclose, in its clicked() signal, an integer.
Here’s the custom button class:
.h:
#include <QtGui>
#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H
class CustomButton : public QPushButton //This simple class allows us to map arguments in the Widget's cicked() signal.
{ //In the project, it's used in the delete-edit buttons so the program knows which part of the Movie/Theater/Screening list we're referring to
Q_OBJECT
public:
CustomButton(QString name,int num, QWidget *parent = 0);
signals:
void clicked(int pos);
private:
QSignalMapper *signalMapper;
};
#endif // CUSTOMBUTTON_H
.cpp:
#include "custombutton.h"
CustomButton::CustomButton(QString name,int num = 0, QWidget *parent) //Our constructor
: QPushButton(name,parent)
{ //Our button's now created and shown, through the superconstructor. Let's take care of its clicked() signal.
signalMapper = new QSignalMapper(this);
connect(this, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(this, num);
connect(signalMapper, SIGNAL(mapped(int)),this, SIGNAL(clicked(int)));
}
And then in my main code I do:
CustomButton *edit_button = new CustomButton("Edit",i,0);
edit_button->setFixedWidth(30);
connect(edit_button,SIGNAL(clicked(int)),this,SLOT(edit_movie(int))); //When the user decides to edit a movie, we set the class'es working_with var to the position of the film in the MovieList and we set the screen to the appropriate one.
CustomButton *del_button = new CustomButton("Delete",i,0); //We pass i as an argument to the button, so it can relate to the movie it's set next to.
del_button->setFixedWidth(45);
connect(del_button,SIGNAL(clicked(int)),this,SLOT(del_movie(int)));
Where i is the number I want it to have in the signal.
Thing is, thorugh the debugger it doesn’t give me a segfault if I press the Delete button. It all happens in the edit one.
As I’m still pretty confused and in a situation where I don’t even know WHAT to ask about, if you need anything else from me please say so and I will provide.
Here’s the backtrace, which I know not how to read:
0 QHash<QObject*, QString>::findNode qhash.h 884 0×69e98594
1 QHash<QObject*, QString>::contains qhash.h 874 0×69e98568
2 QSignalMapper::map qsignalmapper.cpp 267 0×69debe0c
3 QSignalMapper::map qsignalmapper.cpp 257 0×69debda2
4 QSignalMapper::qt_static_metacall moc_qsignalmapper.cpp 64 0×69debfce
5 QMetaObject::activate qobject.cpp 3547 0×69de9baf
6 QAbstractButton::clicked moc_qabstractbutton.cpp 220 0×10cb4b8
7 QAbstractButtonPrivate::emitClicked qabstractbutton.cpp 548 0xe2e517
8 QAbstractButtonPrivate::click qabstractbutton.cpp 541 0xe2e495
9 QAbstractButton::mouseReleaseEvent qabstractbutton.cpp 1123 0xe2f941
10 QWidget::event qwidget.cpp 8362 0xae63de
11 QAbstractButton::event qabstractbutton.cpp 1082 0xe2f7cc
12 QPushButton::event qpushbutton.cpp 683 0xecfeba
13 QApplicationPrivate::notify_helper qapplication.cpp 4554 0xa9c020
14 QApplication::notify qapplication.cpp 4097 0xa9a26a
15 QCoreApplication::notifyInternal qcoreapplication.cpp 876 0×69dd3b76
16 QCoreApplication::sendSpontaneousEvent qcoreapplication.h 234 0×113137e
17 QApplicationPrivate::sendMouseEvent qapplication.cpp 3163 0xa98ad6
18 QETWidget::translateMouseEvent qapplication_win.cpp 3363 0xb03171
19 QtWndProc qapplication_win.cpp 1696 0xafdf66
20 USER32!IsDialogMessageW C:\Windows\syswow64\user32.dll 0 0×76726238
21 USER32!RegisterSystemThread C:\Windows\syswow64\user32.dll 0 0×767278b0
22 ?? 0 0×30000
23 USER32!AllowForegroundActivation C:\Windows\syswow64\user32.dll 0 0×767268ea
24 qt_is_translatable_mouse_event qapplication_win.cpp 1463 0xafd465
25 USER32!GetMessageExtraInfo C:\Windows\syswow64\user32.dll 0 0×76727d31
26 ?? 0
Any heads up as to what might be causing the problem? As I said, the segfault only occurs if I run the program through the Debugger and when I press the "Edit" button, of the CustomButton class. When I normally build&run, the program works 9/10 times. Sometimes, clicking the edit button results in a crash. This erratic behaviour is what caused me to look for help here.
As when I click the button I'm taken to a new screen, I'm suspecting that the problem might lie in the decstructor? Does a blank destructor correctly deconstruct elements of objects of the CustomButton class, seeing as the actual object is passed to the base class constructor? Maybe I've got a leak there?
Unless knowing where you create the objects, it's hard to tell why there is a segfault in QSignalMapper. The pointer to your signal mapper might be invalid at some point in time, so there might be an unwanted deletion.
In some cases, a complete rebuild of your application might be helpful. Also re-running qmake. Just should be on your checklist when you can't explain why there is a segfault ...;)
There is an alternative to QSignalMapper: keep your signal clicked(int) and implement a private slot:
private slots:
this_clicked() {
emit clicked(num);
}
Then put in the constructor:
connect(this, SIGNAL(clicked()), SLOT(this_clicked()));
Related
So I am using WebEngineView in my QML like this:
...
Loader {
// some properties
sourceComponent: WebEngineView {
...
}
}
In the c++ logic I am using QQuickWebEngineProfile::defaultProfile() in the constructor and destructor
MainViewModel(QObject* parent) : QObject(parent)
{
// using QQuickWebEngineProfile::defaultProfile();
// getting cookieStore of the profile and connect it to some slots
}
~MainViewModel()
{
// using QQuickWebEngineProfile::defaultProfile();
// getting cookieStore of the profile and disconnect it from MainViewModel
}
So it's working perfectly, but when I am trying to close my app (calling qApp->quit()), it crashes. If I remove WebEngineView from QML it works, if I remove using of defaultProfile() in c++ it works. But I need these things.
Dump:
1 _threadid ucrtbased 0x7ffb48687c75
2 _threadid ucrtbased 0x7ffb48687e13
3 abort ucrtbased 0x7ffb4869e01d
4 `anonymous namespace'::messageHandler application.cpp 46 0x7ff7c2d2b1bf
5 qt_message_print qlogging.cpp 1844 0x7ffb08317fdf
6 qt_message qlogging.cpp 379 0x7ffb08318657
7 QMessageLogger::fatal qlogging.cpp 890 0x7ffb08316612
8 qt_assert qglobal.cpp 3354 0x7ffb08307a48
9 QAccessible::registerAccessibleInterface qaccessible.cpp 747 0x7ffb01df22bd
10 QAccessible::uniqueId qaccessible.cpp 767 0x7ffb01df2247
11 QQuickWebEngineViewPrivate::widgetChanged qquickwebengineview.cpp 982 0x7ffb4b2b5bda
12 QQuickWebEngineViewPrivate::bindViewAndWidget qquickwebengineview.cpp 972 0x7ffb4b2b5b6e
13 QQuickWebEngineViewPrivate::releaseProfile qquickwebengineview.cpp 200 0x7ffb4b2b2349
14 QtWebEngineCore::ProfileAdapter::~ProfileAdapter profile_adapter.cpp 127 0x7ffad4237f20
15 QtWebEngineCore::ProfileAdapter::`vector deleting destructor' Qt5WebEngineCored 0x7ffad4238678
16 std::default_delete<QtWebEngineCore::DevToolsFrontendQt::NetworkResourceLoader>::operator() memory 1758 0x7ffad41d9a75
17 std::unique_ptr<QtWebEngineCore::WebChannelIPCTransportHost,std::default_delete<QtWebEngineCore::WebChannelIPCTransportHost>>::reset memory 1910 0x7ffad4287857
18 QtWebEngineCore::WebEngineContext::destroy web_engine_context.cpp 339 0x7ffad4295a87
19 QtWebEngineCore::WebEngineContext::destroyContextPostRoutine web_engine_context.cpp 425 0x7ffad4295bf8
20 qt_call_post_routines qcoreapplication.cpp 336 0x7ffb087276ef
21 QApplication::~QApplication qapplication.cpp 714 0x7ffb07767046
...
30 main main.cpp 63 0x7ff7c21d4640
It tried to access main window which at that moment has already been deleted. To resolve this problem I had to delay destruction of my main window. I've done it with
QObject::deleteLater()
I have a code with a QDoubleSpinBox
ui->doubleSpinBoxExposure->setMinimum(0.001);
ui->doubleSpinBoxExposure->setMaximum(1000);
ui->doubleSpinBoxExposure->setSingleStep(1.0);
connect(ui->doubleSpinBoxExposure, SIGNAL(valueChanged(double)),
this, SLOT(OndoubleSpinBoxExposure_valueChanged(double)));
void WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged(double value)
{
if (!camera)
return;
if (camera->isOpen())
{
float exposure = static_cast<float>(value);
float cameraExposure;
camera->setExposure(exposure);
LOG_INFO() <<" setting exposure to " << value << " ms";
cameraExposure = camera->exposure();
LOG_INFO() <<" resulting exposure is " << cameraExposure << " ms";
}
}
The problem is, when I step up in the gui or down, this happens twice.
The starting parameter is value = 2. StepUp calls this function with 3, and directly afterwards with 4. And I have no idea why.
The stack trace is not helpfull:
1 WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged widgetcameraparameter.cpp 311 0x406c17
2 WidgetCameraParameter::qt_static_metacall moc_widgetcameraparameter.cpp 110 0x40811f
3 QMetaObject::activate qobject.cpp 3771 0x12bc2e1
4 QMetaObject::activate qobject.cpp 3633 0x12bc575
5 QDoubleSpinBox::valueChanged moc_qspinbox.cpp 436 0x15e66190
6 QDoubleSpinBoxPrivate::emitSignals qspinbox.cpp 1112 0x15e663b2
7 QAbstractSpinBoxPrivate::setValue qabstractspinbox.cpp 1741 0x15e6174d
8 QAbstractSpinBox::stepBy qabstractspinbox.cpp 643 0x15e62aba
9 QAbstractSpinBox::timerEvent qabstractspinbox.cpp 1246 0x15e5ffea
10 QObject::event qobject.cpp 1232 0x12bc918
11 QWidget::event qwidget.cpp 9347 0x15d0c544
12 QAbstractSpinBox::event qabstractspinbox.cpp 795 0x15e65930
13 QApplicationPrivate::notify_helper qapplication.cpp 3727 0x15cc85ca
14 QApplication::notify qapplication.cpp 3690 0x15cd1f4f
15 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1048 0x1295119
16 QCoreApplication::sendEvent qcoreapplication.h 234 0x12e4d87
17 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 447 0x12e4d87
18 qt_internal_proc(HWND__ *, unsigned int, unsigned int, long) *16 qeventdispatcher_win.cpp 242 0x12e53d5
19 gapfnScSendMessage 0x771162fa
20 ?? 0x5c0f30
21 USER32!GetThreadDesktop 0x77116d3a
22 QEventDispatcherWin32Private::sendTimerEvent qeventdispatcher_win.cpp 456 0x12e4dc9
23 ?? 0x5c0f30
24 USER32!CharPrevW 0x771177c4
25 USER32!DispatchMessageW 0x7711788a
26 QEventDispatcherWin32::processEvents qeventdispatcher_win.cpp 629 0x12e4ae8
27 QWindowsGuiEventDispatcher::processEvents qwindowsguieventdispatcher.cpp 74 0x2496dab7
28 QEventLoop::processEvents qeventloop.cpp 136 0x12937c8
29 QEventLoop::exec qeventloop.cpp 214 0x1293c20
30 QCoreApplication::exec qcoreapplication.cpp 1336 0x129c30e
31 QGuiApplication::exec qguiapplication.cpp 1761 0x8461552
32 QApplication::exec qapplication.cpp 2901 0x15cc84a9
33 qMain main.cpp 28 0x40183d
34 WinMain *16 qtmain_win.cpp 104 0x4094c5
35 main 0x4179ad
Any idea how to debug this further?
EDIT:
This only happens when I debug with breakpoints in the slot. Without the slot is only called once.
The second call of the slot does not happen from any function within the slot function, but only after the slot has ended from the event loop.
You can loop at the complete code:
https://github.com/pospiech/code/tree/master/libdev/devices/CameraViewer
Looking at the QStyle::StyleHint enum, there is an interesting SH_SpinBox_ClickAutoRepeatThreshold constant. You can check its current value for your spin box, like this:
qDebug() << ui->doubleSpinBoxExposure->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold);
This generally returns 500, which is the number of milliseconds after which the auto repeat gets triggered (i.e. if the user holds the mouse press on the up spin button for longer than that threshold, the spin box value will start increasing continuously).
To see if you have a timing issue, try changing that value, using a custom QStyle class like this:
#include <QProxyStyle>
class MyStyle : public QProxyStyle
{
public:
int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const
{
if(stylehint == QStyle::SH_SpinBox_ClickAutoRepeatThreshold)
{
return 2000; //2 seconds threshold
}
return QProxyStyle::styleHint(stylehint, opt, widget, returnData);
}
};
and setting an instance of it to the spin box style:
ui->doubleSpinBoxExposure->setStyle(new MyStyle());
Now it takes a lot (two long seconds) before the auto repeat gets triggered, and your issue should be gone, accordingly.
It looks like you have a freezing gui-thread with your slot.
You can try this code in your slot
void WidgetCameraParameter::OndoubleSpinBoxExposure_valueChanged(double value)
{
#define NUM_LOOPS 1000000000
qDebug() << value;
quint64 i = NUM_LOOPS;
while(i--);
}
To avoid this, you have to move to another thread an operation that consumes a lot of CPU time.
In debug mode its because of autorepeating timer.
Try this code to disable autorepeating in debug and, i think, you`ll understand:
*.h
...
#ifdef QT_DEBUG
bool eventFilter(QObject *watched, QEvent *event) override;
#endif
...
*.c
...
ui->setupUi(this);
#ifdef QT_DEBUG
ui->doubleSpinBoxExposure->installEventFilter(this);
#endif
...
#ifdef QT_DEBUG
bool WidgetCameraParameter::eventFilter(QObject *watched, QEvent *event)
{
QDoubleSpinBox *castSBox = static_cast<QDoubleSpinBox*>(watched);
if(castSBox && event->type()==QEvent::Timer)
{
QTimerEvent *tEvent = static_cast<QTimerEvent*>(event);
if(tEvent)
qDebug() << "<--QEvent::Timer-->" << tEvent->timerId();
return true;
}
return QObject::eventFilter(watched,event);
}
#endif
I have a simple program that reads an image from a camera and converts it to Qimage. This is then converted into a pixmap which is supposed to be drawn in paintEvent(QPaintEvent * event)
The problem is that the program crashes when the widget is drawn. Here while leaving on_pushButtonTakeImage_clicked()
This is the basic code:
void MainWindow::on_pushButtonTakeImage_clicked()
{
bool isReady = camera->initialize();
if (isReady){
camera->openCamera();
camera->capture();
ui->widgetCameraImage->setImage(camera->image());
}
}
void QCameraImageBase::setImage(const QImage & image)
{
Q_D(QCameraImageBase);
d->pixmap = QPixmap::fromImage(image);
update(); // calls paintEvent
}
The debuggin point within the overloaded paintEvent(QPaintEvent * event) is never called.
This is the trace
1 ntdll!RtlQueryPerformanceCounter 0x77603266
2 ntdll!RtlQueryPerformanceCounter 0x776034a1
3 ntdll!RtlpNtEnumerateSubKey 0x776a10c3
4 ntdll!RtlUlonglongByteSwap 0x7765abe2
5 ?? 0x1a830000
6 ntdll!RtlQueryPerformanceCounter 0x776034a1
7 msvcrt!malloc 0x77149d45
8 libstdc++-6!_Znwj 0x7c999a
9 QRasterPaintEngine::createState qpaintengine_raster.cpp 686 0xd5f469
10 QPainter::begin qpainter.cpp 1754 0xd6f375
11 QPainter::QPainter qpainter.cpp 1476 0xd6fc60
12 QWidgetPrivate::drawWidget qwidget.cpp 5560 0xe1a4012
13 QWidgetBackingStore::doSync qwidgetbackingstore.cpp 1375 0xe177a66
14 QWidgetBackingStore::sync qwidgetbackingstore.cpp 1156 0xe177e95
15 QWidgetPrivate::syncBackingStore qwidget.cpp 1951 0xe19181c
16 QWidget::event qwidget.cpp 9216 0xe1ac102
17 QMainWindow::event qmainwindow.cpp 1342 0xe2c8ac0
18 QApplicationPrivate::notify_helper qapplication.cpp 3732 0xe1686de
19 QApplication::notify qapplication.cpp 3695 0xe172093
20 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1050 0x6bb0b5d1
... <Mehr>
I work with Qt Creator and mingw. Anything I can do to fix this error or find more about the cause?
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 developed an app in Qt/C++, it's a file browser like. Currently when deleting some files or copying some files, I have a thread who manage the overall app and copy and another one just created to display a progress bar with the Cancel button. It's very basic but as I'm browsing an Android device file system any access to delete copy freeze the UI and the access is done by the application thread. It's not an issue as I don't want the user to play with the UI when copying or deleting.
My issue is mainly a real time issue with the threading. When I'm using Qt creator as IDE and debugging, I do not have any issue the delete works and the progress bar is also display without any issue. When I'm just using the app out of Qt Creator the app is crashing often when trying to display the dialog box.
I'm pretty sure it's link to the threading. when using the debugger and Qt creator the overall app slowing down to trace, debug...
Here is the code of my TreeView.cpp when asking to delete for example:
DialogProgressIndicator *DeleteProgress = new DialogProgressIndicator;
DeleteProgress->moveToThread(&ProgressThread);
connect(&ProgressThread, &QThread::finished, DeleteProgress, &QObject::deleteLater);
connect(this, &PulsTreeWidget::DisplayProgress, DeleteProgress, &DialogProgressIndicator::ShowDlg);
connect(this, &PulsTreeWidget::UpdateProgress, DeleteProgress, &DialogProgressIndicator::UpdateIndicator);
connect(this, &PulsTreeWidget::CloseProgress, DeleteProgress, &DialogProgressIndicator::CloseDlg);
connect(DeleteProgress,&DialogProgressIndicator::CancelAction, this, &PulsTreeWidget::CatchActionCancel);
ProgressThread.start();
DisplayProgress();
And when the delete is finished, I'm closing everything following the method below:
CloseProgress();
ProgressThread.quit();
disconnect(&ProgressThread, &QThread::finished, FileTransferProgress, &QObject::deleteLater);
disconnect(this, &PulsTreeWidget::DisplayProgress, FileTransferProgress, &DialogProgressIndicator::ShowDlg);
disconnect(this, &PulsTreeWidget::UpdateProgress, FileTransferProgress, &DialogProgressIndicator::UpdateIndicator);
disconnect(this, &PulsTreeWidget::CloseProgress, FileTransferProgress, &DialogProgressIndicator::CloseDlg);
disconnect(FileTransferProgress,&DialogProgressIndicator::CancelAction, this, &PulsTreeWidget::CatchActionCancel);
the class PulsTreeWidget is defined as below:
class PulsTreeWidget : public QTreeWidget
{
Q_OBJECT
QThread ProgressThread;
public:
PulsTreeWidget(PulsDeviceMngr& device, PulsMainUI& parent);
~PulsTreeWidget();
signals:
void DisplayProgress();
void CloseProgress();
void UpdateProgress(int);
The Progress bar is managed by the class
DialogProgressIndicator.cpp
#include <QApplication>
#include "dialogprogressindicator.h"
#include "ui_dialogprogressindicator.h"
DialogProgressIndicator::DialogProgressIndicator(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogProgressIndicator)
{
ui->setupUi(this);
ui->progressBar->setRange(0,100);
ui->progressBar->setValue(1);
connect(ui->Cancel, SIGNAL(clicked()), this, SLOT(onClickCancel()));
}
void DialogProgressIndicator::ShowDlg() {
ui->progressBar->show();
}
void DialogProgressIndicator::CloseDlg() {
ui->progressBar->close();
}
DialogProgressIndicator::~DialogProgressIndicator()
{
delete ui;
}
void DialogProgressIndicator::UpdateIndicator(int value) {
ui->progressBar->setValue(value);
QApplication::processEvents();
}
void DialogProgressIndicator::onClickCancel() {
emit CancelAction();
disconnect(ui->Cancel, SIGNAL(clicked()), this, SLOT(onClickCancel()));
}
I have followed the Qt guideline but it still crashing when doing the "DisplayProgress"
Any idea ? It's really crashing when in the other thread I'm doing the
void DialogProgressIndicator::ShowDlg() {
ui->progressBar->show();
}
I'm adding the crash log:
Application Specific Information:
abort() called
Thread 0:: Dispatch queue: com.apple.main-thread
0 com.apple.AppKit 0x00007fff89e6561f -[NSView(NSInternal) _allocAuxiliary:] + 833
1 com.apple.AppKit 0x00007fff89e67a59 -[NSView _commonAwake] + 36
2 com.apple.AppKit 0x00007fff89e6c841 -[NSView initWithFrame:] + 457
3 libqcocoa.dylib 0x0000000103c2078f 0x103c0c000 + 83855
4 libqcocoa.dylib 0x0000000103c20a1d 0x103c0c000 + 84509
5 libqcocoa.dylib 0x0000000103c18f36 0x103c0c000 + 53046
6 libqcocoa.dylib 0x0000000103c14b72 0x103c0c000 + 35698
7 QtGui 0x0000000100f77603 QWindow::create() + 51
8 QtWidgets 0x0000000101509e13 QWidgetPrivate::create_sys(unsigned long long, bool, bool) + 1107
9 QtWidgets 0x00000001014df86c QWidget::create(unsigned long long, bool, bool) + 444
10 QtWidgets 0x00000001014eeebd QWidget::setVisible(bool) + 237
11 QtWidgets 0x000000010169679d QDialog::setVisible(bool) + 205
12 com.yourcompany.puls_connect 0x0000000100022305 DialogProgressIndicator::ShowDlg() + 21
13 com.yourcompany.puls_connect 0x000000010001a51e void QtPrivate::FunctionPointer<void (DialogProgressIndicator::*)()>::call<void, void>(void (DialogProgressIndicator::*)(), DialogProgressIndicator*, void**) + 142
14 com.yourcompany.puls_connect 0x000000010001a3fa QtPrivate::QSlotObject<void (DialogProgressIndicator::*)(), void, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) + 202
15 QtCore 0x0000000100bfdda2 QMetaObject::activate(QObject*, int, int, void**) + 1874
16 com.yourcompany.puls_connect 0x00000001000242db PulsTreeWidget::DisplayProgress() + 43
Remember that you can use GUI classes only in main thread. For parallel task use
QFutureWatcher:
WaitDialog waitDlg(this);
connect(this, SIGNAL(progress(int)), &waitDlg, SLOT(setProgress(int)));
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), &waitDlg, SLOT(close()));
connect(&watcher, SIGNAL(canceled()), &waitDlg, SLOT(close()));
QFuture<void> future = QtConcurrent::run([] () {/*do parallel task here*/});
watcher.setFuture(future);
waitDlg.exec();