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/overlay_layer.cpp
source/scwx/qt/map/radar_product_layer.cpp source/scwx/qt/map/radar_product_layer.cpp
source/scwx/qt/map/radar_range_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 set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp
source/scwx/qt/settings/palette_settings.hpp) source/scwx/qt/settings/palette_settings.hpp)
set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp
@ -135,6 +137,8 @@ set(PROJECT_SOURCES ${HDR_MAIN}
${UI_MAIN} ${UI_MAIN}
${HDR_MAP} ${HDR_MAP}
${SRC_MAP} ${SRC_MAP}
${HDR_REQUEST}
${SRC_REQUEST}
${HDR_SETTINGS} ${HDR_SETTINGS}
${SRC_SETTINGS} ${SRC_SETTINGS}
${HDR_UI} ${HDR_UI}
@ -162,6 +166,8 @@ source_group("Source Files\\manager" FILES ${SRC_MANAGER})
source_group("UI Files\\main" FILES ${UI_MAIN}) source_group("UI Files\\main" FILES ${UI_MAIN})
source_group("Header Files\\map" FILES ${HDR_MAP}) source_group("Header Files\\map" FILES ${HDR_MAP})
source_group("Source Files\\map" FILES ${SRC_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("Header Files\\settings" FILES ${HDR_SETTINGS})
source_group("Source Files\\settings" FILES ${SRC_SETTINGS}) source_group("Source Files\\settings" FILES ${SRC_SETTINGS})
source_group("Header Files\\ui" FILES ${HDR_UI}) 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(); BOOST_LOG_TRIVIAL(info) << "Selected: " << file.toStdString();
manager::RadarProductManager::LoadFile( std::shared_ptr<request::NexradFileRequest> request =
file.toStdString(), std::make_shared<request::NexradFileRequest>();
[=](std::shared_ptr<wsr88d::NexradFile> nexradFile)
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::shared_ptr<wsr88d::Ar2vFile> level2File =
std::dynamic_pointer_cast<wsr88d::Ar2vFile>(nexradFile); std::dynamic_pointer_cast<wsr88d::Ar2vFile>(nexradFile);
std::shared_ptr<wsr88d::Level3File> level3File = std::shared_ptr<wsr88d::Level3File> level3File =
@ -250,8 +258,9 @@ void MainWindow::on_actionOpen_triggered()
messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->setAttribute(Qt::WA_DeleteOnClose);
messageBox->open(); messageBox->open();
} }
}, });
this);
manager::RadarProductManager::LoadFile(file.toStdString(), request);
}); });
dialog->open(); dialog->open();

View file

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

View file

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