Use signals/slots to prevent QObject lifetime issues

This commit is contained in:
Dan Paulat 2022-02-13 16:19:47 -06:00
parent 9b90189566
commit a47460842b
7 changed files with 125 additions and 41 deletions

View file

@ -88,6 +88,8 @@ set(SRC_MAP source/scwx/qt/map/color_table_layer.cpp
source/scwx/qt/map/overlay_layer.cpp
source/scwx/qt/map/radar_product_layer.cpp
source/scwx/qt/map/radar_range_layer.cpp)
set(HDR_REQUEST source/scwx/qt/request/nexrad_file_request.hpp)
set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp)
set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
source/scwx/qt/settings/palette_settings.hpp)
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
@ -135,6 +137,8 @@ set(PROJECT_SOURCES ${HDR_MAIN}
${UI_MAIN}
${HDR_MAP}
${SRC_MAP}
${HDR_REQUEST}
${SRC_REQUEST}
${HDR_SETTINGS}
${SRC_SETTINGS}
${HDR_UI}
@ -162,6 +166,8 @@ source_group("Source Files\\manager" FILES ${SRC_MANAGER})
source_group("UI Files\\main" FILES ${UI_MAIN})
source_group("Header Files\\map" FILES ${HDR_MAP})
source_group("Source Files\\map" FILES ${SRC_MAP})
source_group("Header Files\\request" FILES ${HDR_REQUEST})
source_group("Source Files\\request" FILES ${SRC_REQUEST})
source_group("Header Files\\settings" FILES ${HDR_SETTINGS})
source_group("Source Files\\settings" FILES ${SRC_SETTINGS})
source_group("Header Files\\ui" FILES ${HDR_UI})

View file

@ -223,10 +223,18 @@ void MainWindow::on_actionOpen_triggered()
{
BOOST_LOG_TRIVIAL(info) << "Selected: " << file.toStdString();
manager::RadarProductManager::LoadFile(
file.toStdString(),
[=](std::shared_ptr<wsr88d::NexradFile> nexradFile)
std::shared_ptr<request::NexradFileRequest> request =
std::make_shared<request::NexradFileRequest>();
connect(
request.get(),
&request::NexradFileRequest::RequestComplete,
this,
[=](std::shared_ptr<request::NexradFileRequest> request)
{
std::shared_ptr<wsr88d::NexradFile> nexradFile =
request->nexrad_file();
std::shared_ptr<wsr88d::Ar2vFile> level2File =
std::dynamic_pointer_cast<wsr88d::Ar2vFile>(nexradFile);
std::shared_ptr<wsr88d::Level3File> level3File =
@ -250,8 +258,9 @@ void MainWindow::on_actionOpen_triggered()
messageBox->setAttribute(Qt::WA_DeleteOnClose);
messageBox->open();
}
},
this);
});
manager::RadarProductManager::LoadFile(file.toStdString(), request);
});
dialog->open();

View file

@ -28,9 +28,8 @@ static const std::string logPrefix_ =
typedef std::function<std::shared_ptr<wsr88d::NexradFile>()>
CreateNexradFileFunction;
static void LoadNexradFile(CreateNexradFileFunction load,
FileLoadCompleteFunction onComplete,
QObject* context);
static void LoadNexradFile(CreateNexradFileFunction load,
std::shared_ptr<request::NexradFileRequest> request);
static constexpr uint32_t NUM_RADIAL_GATES_0_5_DEGREE =
common::MAX_0_5_DEGREE_RADIALS * common::MAX_DATA_MOMENT_GATES;
@ -210,33 +209,29 @@ void RadarProductManager::Initialize()
p->initialized_ = true;
}
void RadarProductManager::LoadData(std::istream& is,
FileLoadCompleteFunction onComplete,
QObject* context)
void RadarProductManager::LoadData(
std::istream& is, std::shared_ptr<request::NexradFileRequest> request)
{
LoadNexradFile(
[=, &is]() -> std::shared_ptr<wsr88d::NexradFile> {
return wsr88d::NexradFileFactory::Create(is);
},
onComplete,
context);
request);
}
void RadarProductManager::LoadFile(const std::string& filename,
FileLoadCompleteFunction onComplete,
QObject* context)
void RadarProductManager::LoadFile(
const std::string& filename,
std::shared_ptr<request::NexradFileRequest> request)
{
LoadNexradFile(
[=]() -> std::shared_ptr<wsr88d::NexradFile> {
return wsr88d::NexradFileFactory::Create(filename);
},
onComplete,
context);
request);
}
static void LoadNexradFile(CreateNexradFileFunction load,
FileLoadCompleteFunction onComplete,
QObject* context)
static void LoadNexradFile(CreateNexradFileFunction load,
std::shared_ptr<request::NexradFileRequest> request)
{
scwx::util::async(
[=]()
@ -249,17 +244,10 @@ static void LoadNexradFile(CreateNexradFileFunction load,
lock.unlock();
if (onComplete != nullptr)
if (request != nullptr)
{
if (context == nullptr)
{
onComplete(nexradFile);
}
else
{
QMetaObject::invokeMethod(context,
[=]() { onComplete(nexradFile); });
}
request->set_nexrad_file(nexradFile);
emit request->RequestComplete(request);
}
});
}

View file

@ -2,6 +2,7 @@
#include <scwx/common/types.hpp>
#include <scwx/qt/config/radar_site.hpp>
#include <scwx/qt/request/nexrad_file_request.hpp>
#include <scwx/wsr88d/ar2v_file.hpp>
#include <scwx/wsr88d/level3_file.hpp>
@ -17,9 +18,6 @@ namespace qt
namespace manager
{
typedef std::function<void(std::shared_ptr<wsr88d::NexradFile>)>
FileLoadCompleteFunction;
class RadarProductManagerImpl;
class RadarProductManager : public QObject
@ -49,12 +47,12 @@ public:
static std::shared_ptr<RadarProductManager>
Instance(const std::string& radarSite);
static void LoadData(std::istream& is,
FileLoadCompleteFunction onComplete,
QObject* context = nullptr);
static void LoadFile(const std::string& filename,
FileLoadCompleteFunction onComplete,
QObject* context = nullptr);
static void
LoadData(std::istream& is,
std::shared_ptr<request::NexradFileRequest> request = nullptr);
static void
LoadFile(const std::string& filename,
std::shared_ptr<request::NexradFileRequest> request = nullptr);
signals:
void Level2DataLoaded();

View file

@ -0,0 +1,44 @@
#include <scwx/qt/request/nexrad_file_request.hpp>
#include <boost/log/trivial.hpp>
namespace scwx
{
namespace qt
{
namespace request
{
static const std::string logPrefix_ =
"[scwx::qt::request::nexrad_file_request] ";
class NexradFileRequestImpl
{
public:
explicit NexradFileRequestImpl() : nexradFile_ {nullptr} {}
~NexradFileRequestImpl() {}
std::shared_ptr<wsr88d::NexradFile> nexradFile_;
};
NexradFileRequest::NexradFileRequest() :
p(std::make_unique<NexradFileRequestImpl>())
{
}
NexradFileRequest::~NexradFileRequest() = default;
std::shared_ptr<wsr88d::NexradFile> NexradFileRequest::nexrad_file() const
{
return p->nexradFile_;
}
void NexradFileRequest::set_nexrad_file(
std::shared_ptr<wsr88d::NexradFile> nexradFile)
{
p->nexradFile_ = nexradFile;
}
} // namespace request
} // namespace qt
} // namespace scwx

View file

@ -0,0 +1,39 @@
#pragma once
#include <scwx/wsr88d/nexrad_file.hpp>
#include <memory>
#include <QObject>
namespace scwx
{
namespace qt
{
namespace request
{
class NexradFileRequestImpl;
class NexradFileRequest : public QObject
{
Q_OBJECT
public:
explicit NexradFileRequest();
~NexradFileRequest();
std::shared_ptr<wsr88d::NexradFile> nexrad_file() const;
void set_nexrad_file(std::shared_ptr<wsr88d::NexradFile> nexradFile);
private:
std::unique_ptr<NexradFileRequestImpl> p;
signals:
void RequestComplete(std::shared_ptr<NexradFileRequest> request);
};
} // namespace request
} // namespace qt
} // namespace scwx

View file

@ -102,7 +102,7 @@
<context>
<name>scwx::qt::main::MainWindow</name>
<message>
<location filename="../source/scwx/qt/main/main_window.cpp" line="248"/>
<location filename="../source/scwx/qt/main/main_window.cpp" line="256"/>
<source>Unrecognized NEXRAD Product:</source>
<translation type="unfinished"></translation>
</message>