Hallo,
if I create an path object (class Path : public QObject, public QGraphicsPathItem) in an other std::thread then his parent item (class Anchor : public QObject, public QGraphicsPixmapItem), it crashes.
The funny thing is, that it doesn't crashes if the QMainWindow that holds the QGraphicScene has no parent. If it's parent is a QTabWidget it crashes.
Anchor.cpp
void Anchor::addDistanceValue(double distanceValue) {
mutex.lock();
bool stillWorking = isWorking;
mutex.unlock();
if(!stillWorking){
mutex.lock();
isWorking = true;
mutex.unlock();
if (wallCheckerThread.joinable()){
//QTime timeStamp = QTime::currentTime();
wallCheckerThread.join();
//qDebug() << "wait to join anker: " << id << "in " << timeStamp.msecsTo(QTime::currentTime()) << "ms";
}
wallCheckerThread = std::thread([&](double distanceValue){
classMutex.lock();
mutex.lock();
Path* item = new Path(distanceValue * 100, this); // <<--- here is the problem, the this
mutex.unlock();
//item->setPos(pos());
item->setVisible(false);
//scene()->addItem(item);
classMutex.unlock();
checkAdditionalPathLossChanges(distanceValue, item);
qDebug
() <<
"Anker " << getId
() <<
": " << timeStamp.
msecsTo(QTime::currentTime()) <<
"ms";
pen.setColor(0x8888ff);
item->setPen(pen);
item->setFlags(0);
item->setAcceptedMouseButtons(Qt::NoButton);
distanceVector.push_back(distanceValue);
ellipses.append(item);
if (distanceVector.length() > 1){
distanceVector.pop_front();
classMutex.lock();
delete ellipses.first();
//scene()->removeItem(ellipses.first());
classMutex.unlock();
if (!ellipses.isEmpty())
ellipses.pop_front();
}
item->setVisible(true);
mutex.lock();
isWorking = false;
mutex.unlock();
}, distanceValue);
}else{
qDebug() << "skipped anker " << id;
}
}
void Anchor::addDistanceValue(double distanceValue) {
mutex.lock();
bool stillWorking = isWorking;
mutex.unlock();
if(!stillWorking){
mutex.lock();
isWorking = true;
mutex.unlock();
if (wallCheckerThread.joinable()){
//QTime timeStamp = QTime::currentTime();
wallCheckerThread.join();
//qDebug() << "wait to join anker: " << id << "in " << timeStamp.msecsTo(QTime::currentTime()) << "ms";
}
wallCheckerThread = std::thread([&](double distanceValue){
QTime timeStamp = QTime::currentTime();
classMutex.lock();
mutex.lock();
Path* item = new Path(distanceValue * 100, this); // <<--- here is the problem, the this
mutex.unlock();
//item->setPos(pos());
item->setVisible(false);
//scene()->addItem(item);
classMutex.unlock();
checkAdditionalPathLossChanges(distanceValue, item);
qDebug() << "Anker " << getId() << ": " << timeStamp.msecsTo(QTime::currentTime()) << "ms";
QPen pen;
pen.setColor(0x8888ff);
item->setPen(pen);
item->setFlags(0);
item->setAcceptedMouseButtons(Qt::NoButton);
distanceVector.push_back(distanceValue);
ellipses.append(item);
if (distanceVector.length() > 1){
distanceVector.pop_front();
classMutex.lock();
delete ellipses.first();
//scene()->removeItem(ellipses.first());
classMutex.unlock();
if (!ellipses.isEmpty())
ellipses.pop_front();
}
item->setVisible(true);
mutex.lock();
isWorking = false;
mutex.unlock();
}, distanceValue);
}else{
qDebug() << "skipped anker " << id;
}
}
To copy to clipboard, switch view to plain text mode
path.h
#include <QGraphicsItem>
#include <QObject>
#include <QGraphicsSceneMouseEvent>
{
Q_OBJECT
public:
{
myPath
->addEllipse
(QRectF(-radius,
-radius,radius
* 2, radius
* 2));
setPath(*myPath);
setZValue(1);
}
enum { Type = UserType + 3 };
int type() const { return Type; }
void addPainterPath
(QPainterPath path
){ *myPath
+= path; setPath
(*myPath
);
}
protected:
// QGraphicsEllipseItem *item;
}
}
};
#include <QGraphicsItem>
#include <QObject>
#include <QGraphicsSceneMouseEvent>
class Path : public QObject, public QGraphicsPathItem
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
public:
explicit Path(qreal radius, QGraphicsItem *parent = 0):
QGraphicsPathItem(parent) // << here it crashes (path.h 15)
{
myPath = new QPainterPath();
myPath->addEllipse(QRectF(-radius,-radius,radius * 2, radius * 2));
setPath(*myPath);
setZValue(1);
}
enum { Type = UserType + 3 };
int type() const { return Type; }
void addPainterPath(QPainterPath path){ *myPath += path; setPath(*myPath);}
QPainterPath* getPainterPath() {return myPath; }
protected:
// QGraphicsEllipseItem *item;
void mousePressEvent(QGraphicsSceneMouseEvent *event){
QGraphicsPathItem::mousePressEvent(event);
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event){
QGraphicsPathItem::mouseMoveEvent(event);
}
QPainterPath *myPath;
};
To copy to clipboard, switch view to plain text mode
working if its used this way:
#include <QApplication>
#include <QFile>
#include <QObject>
#include <QDebug>
#include "serialwidget.h"
#include "radarwidget.h"
int main(int argc, char *argv[])
{
RadarWidget radarWidget;
radarWidget.show();
SerialWidget mainWindow;
mainWindow.show();
QObject::connect(&mainWindow,
SIGNAL(newDistanceData
(int,
double)),
&radarWidget,
SLOT(addNodeDistance
(int,
double)));
radarWidget.setSettingsProvider(mainWindow.getSettingsProvider());
return app.exec();
////////////////////////
just as additional info:
the signal is passed to the right anchor
void RadarGraphicsView::addNodeDistance(int id, double distance){
if(anchors.length() == 0){
connect(timer, SIGNAL(timeout()), this, SLOT(calculateLocation()));
timer->start(1000);
}
for(int i = 0; i < anchors.length(); i++){
if(anchors.at(i)->getId() == id){
anchors.at(i)->addDistanceValue(distance);
anchors.at(i)->update();
this->scene()->update();
return;
}
}
Anchor::classMutex.lock();
Anchor *newAnchor = new Anchor(id);
this->scene()->addItem(newAnchor);
Anchor::classMutex.unlock();
double x = settings->getSetting(id, "x");
double y = settings->getSetting(id, "y");
newAnchor->setPos(x,y);
newAnchor->addDistanceValue(distance);
anchors.append(newAnchor);
}
////////////////////////////////////////
}
#include <QApplication>
#include <QFile>
#include <QObject>
#include <QDebug>
#include "serialwidget.h"
#include "radarwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
RadarWidget radarWidget;
radarWidget.show();
SerialWidget mainWindow;
mainWindow.show();
QObject::connect(&mainWindow, SIGNAL(newDistanceData(int, double)), &radarWidget, SLOT(addNodeDistance(int, double)));
radarWidget.setSettingsProvider(mainWindow.getSettingsProvider());
return app.exec();
////////////////////////
just as additional info:
the signal is passed to the right anchor
void RadarGraphicsView::addNodeDistance(int id, double distance){
if(anchors.length() == 0){
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(calculateLocation()));
timer->start(1000);
QThread::msleep(20);
}
for(int i = 0; i < anchors.length(); i++){
if(anchors.at(i)->getId() == id){
anchors.at(i)->addDistanceValue(distance);
anchors.at(i)->update();
this->scene()->update();
return;
}
}
Anchor::classMutex.lock();
Anchor *newAnchor = new Anchor(id);
this->scene()->addItem(newAnchor);
Anchor::classMutex.unlock();
double x = settings->getSetting(id, "x");
double y = settings->getSetting(id, "y");
newAnchor->setPos(x,y);
newAnchor->addDistanceValue(distance);
anchors.append(newAnchor);
}
////////////////////////////////////////
}
To copy to clipboard, switch view to plain text mode
it isnt working this way:
SerialWidget
::SerialWidget(QWidget *parent
) : ui(new Ui::SerialWidget)
{
ui->setupUi(this);
Pi = 3.1415;
ui
->baudRateBox
->setInsertPolicy
(QComboBox::NoInsert);
connect(ui->serialPortInfoListBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showPortInfo(int)));
connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCustomBaudRatePolicy(int)));
//connect(ui->actionSaveMeasurement, SIGNAL(triggered())
//connect(ui->localEchoCheckBox, SIGNAL(clicked(bool)), ui->console, SLOT(setLocalEchoEnabled(bool)));
fillPortsParameters();
fillPortsInfo();
updateSettings();
this->showMaximized();
deviceData.clear();
replayTool = new ReplayTool();
replayTool->moveToThread(&replayToolThread);
replayToolThread.
start(QThread::LowestPriority);
ui->cBDeviceSelector->blockSignals(true);
ui->cBDeviceSelector->insertItem(0,"General Settings");
ui->cBDeviceSelector->blockSignals(false);
ui->cBDeviceSelector->setDuplicatesEnabled(false);
on_friisOkPushButton_clicked();
deviceSettings = new SettingsProvider(&friisDefaultSettings);
rssiFilter = new RssiFilter();
isReplayPaused = false;
// if the qmainwindow is a chiild of this object ----------------------|
QObject::connect(this,
SIGNAL(newDistanceData
(int,
double)), ui
->sWRadar,
SLOT(addNodeDistance
(int,
double)));
// <<--- the radar is a child of the mainwindow ui->sWRadar->setSettingsProvider(deviceSettings);
}
SerialWidget::SerialWidget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SerialWidget)
{
ui->setupUi(this);
Pi = 3.1415;
intValidator = new QIntValidator(0, 3000000, this);
ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert);
connect(ui->serialPortInfoListBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showPortInfo(int)));
connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), this, SLOT(checkCustomBaudRatePolicy(int)));
//connect(ui->actionSaveMeasurement, SIGNAL(triggered())
//connect(ui->localEchoCheckBox, SIGNAL(clicked(bool)), ui->console, SLOT(setLocalEchoEnabled(bool)));
fillPortsParameters();
fillPortsInfo();
updateSettings();
this->showMaximized();
deviceData.clear();
replayTool = new ReplayTool();
replayTool->moveToThread(&replayToolThread);
connect(replayTool, SIGNAL(sigDataRecieved(QByteArray)), this, SLOT(readData(QByteArray)));
replayToolThread.start(QThread::LowestPriority);
ui->cBDeviceSelector->blockSignals(true);
ui->cBDeviceSelector->insertItem(0,"General Settings");
ui->cBDeviceSelector->blockSignals(false);
ui->cBDeviceSelector->setDuplicatesEnabled(false);
on_friisOkPushButton_clicked();
deviceSettings = new SettingsProvider(&friisDefaultSettings);
rssiFilter = new RssiFilter();
isReplayPaused = false;
// if the qmainwindow is a chiild of this object ----------------------|
QObject::connect(this, SIGNAL(newDistanceData(int, double)), ui->sWRadar, SLOT(addNodeDistance(int, double))); // <<--- the radar is a child of the mainwindow
ui->sWRadar->setSettingsProvider(deviceSettings);
}
To copy to clipboard, switch view to plain text mode
the debugger says:
SIGSEGV
Segmantation fault
stack:
0 ?? 0x1d2bf51c
1 QCoreApplicationPrivate::checkReceiverThread 513 0x6b929693
6 QGraphicsScenePrivate::setActivePanelHelper 743 0x94a1c63
9 QGraphicsItemPrivate::setParentItemHelper 1222 0x947b90a
14 Path::Path path.h 15 0x43010a
15 Anchor::__lambda2::operator() anchor.cpp 364 0x40f3cb
16 std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)>::_M_invoke<0u>(std::_Index_tuple<0u>) functional 1732 0x41184f
17 std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)>::operator()(void) functional 1720 0x41173c
18 std::thread::_Impl<std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)> >::_M_run(void) thread 115 0x4116a4
19 libstdc++-6!execute_native_thread_routine C:\Qt\5.3\mingw482_32\bin\libstdc++-6.dll 0xffe58f
20 pthread_create_wrapper C:\Qt\Tools\mingw482_32\opt\bin\libwinpthread-1.dll 0x64944e4b
21 wtoi64 C:\Windows\SysWOW64\msvcrt.dll 0x759c0bc4
22 msvcrt!_beginthreadex C:\Windows\SysWOW64\msvcrt.dll 0x759c0cec
23 KERNEL32!BaseThreadInitThunk C:\Windows\SysWOW64\kernel32.dll 0x75e5919f
24 ntdll!RtlInitializeExceptionChain C:\Windows\SYSTEM32\ntdll.dll 0x77e8a8cb
25 ntdll!RtlInitializeExceptionChain C:\Windows\SYSTEM32\ntdll.dll 0x77e8a8a1
26 ??
0 ?? 0x1d2bf51c
1 QCoreApplicationPrivate::checkReceiverThread 513 0x6b929693
2 QApplication::notify 2791 0x91eb4ba
3 QCoreApplication::notifyInternal 935 0x6b929f96
4 QCoreApplication::sendEvent 237 0x9536429
5 QGraphicsScene::setFocus 2969 0x94a835a
6 QGraphicsScenePrivate::setActivePanelHelper 743 0x94a1c63
7 QGraphicsScene::setActivePanel 5644 0x94b180c
8 QGraphicsItem::setActive 3188 0x94813fc
9 QGraphicsItemPrivate::setParentItemHelper 1222 0x947b90a
10 QGraphicsItem::setParentItem 1685 0x947ce1b
11 QGraphicsItem::QGraphicsItem 1399 0x947c412
12 QAbstractGraphicsShapeItem::QAbstractGraphicsShapeItem 8076 0x948c56a
13 QGraphicsPathItem::QGraphicsPathItem 8217 0x948c8c9
14 Path::Path path.h 15 0x43010a
15 Anchor::__lambda2::operator() anchor.cpp 364 0x40f3cb
16 std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)>::_M_invoke<0u>(std::_Index_tuple<0u>) functional 1732 0x41184f
17 std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)>::operator()(void) functional 1720 0x41173c
18 std::thread::_Impl<std::_Bind_simple<Anchor::addDistanceValue(double)::__lambda2(double)> >::_M_run(void) thread 115 0x4116a4
19 libstdc++-6!execute_native_thread_routine C:\Qt\5.3\mingw482_32\bin\libstdc++-6.dll 0xffe58f
20 pthread_create_wrapper C:\Qt\Tools\mingw482_32\opt\bin\libwinpthread-1.dll 0x64944e4b
21 wtoi64 C:\Windows\SysWOW64\msvcrt.dll 0x759c0bc4
22 msvcrt!_beginthreadex C:\Windows\SysWOW64\msvcrt.dll 0x759c0cec
23 KERNEL32!BaseThreadInitThunk C:\Windows\SysWOW64\kernel32.dll 0x75e5919f
24 ntdll!RtlInitializeExceptionChain C:\Windows\SYSTEM32\ntdll.dll 0x77e8a8cb
25 ntdll!RtlInitializeExceptionChain C:\Windows\SYSTEM32\ntdll.dll 0x77e8a8a1
26 ??
To copy to clipboard, switch view to plain text mode
Bookmarks