# HG changeset patch # User František Kučera # Date 1538333675 -7200 # Node ID b13e7ed9eea3b457e83adb199e60b8576d21aabb # Parent ac70c7af6a9bd76a9c9173775cbdc9c0e8ee817f better use of signal/slot mechanism, threads, Qt::ConnectionType::QueuedConnection diff -r ac70c7af6a9b -r b13e7ed9eea3 .hgignore --- a/.hgignore Sun Sep 30 18:34:34 2018 +0200 +++ b/.hgignore Sun Sep 30 20:54:35 2018 +0200 @@ -1,6 +1,7 @@ syntax: glob *~ +CMakeLists.txt.user syntax: regexp @@ -10,5 +11,3 @@ ^dist/ ^build/ ^nbproject/private/ - -^.*\.qtcreator\.(config|creator|files|includes) diff -r ac70c7af6a9b -r b13e7ed9eea3 src/QtRelationalReaderStringHadler.h --- a/src/QtRelationalReaderStringHadler.h Sun Sep 30 18:34:34 2018 +0200 +++ b/src/QtRelationalReaderStringHadler.h Sun Sep 30 20:54:35 2018 +0200 @@ -10,63 +10,30 @@ using namespace relpipe::reader; using namespace relpipe::reader::handlers; -// signal/slot parameters must be declared here and registered with qRegisterMetaType() - -Q_DECLARE_METATYPE(string_t) -Q_DECLARE_METATYPE(std::vector) - class QtRelationalReaderStringHadler : public QObject, public RelationalReaderStringHadler { - Q_OBJECT -private: - RelationalReaderStringHadler* target; -public: - QtRelationalReaderStringHadler(QObject* parent, RelationalReaderStringHadler* target) : - QObject(parent), target(target) { - - // see Q_DECLARE_METATYPE above - qRegisterMetaType(); - qRegisterMetaType> (); - - QObject::connect(this, &QtRelationalReaderStringHadler::signal_startRelation, this, &QtRelationalReaderStringHadler::slot_startRelation); - QObject::connect(this, &QtRelationalReaderStringHadler::signal_attribute, this, &QtRelationalReaderStringHadler::slot_attribute); - QObject::connect(this, &QtRelationalReaderStringHadler::signal_endOfPipe, this, &QtRelationalReaderStringHadler::slot_endOfPipe); + Q_OBJECT +public: + QtRelationalReaderStringHadler(QObject* parent) : QObject(parent) { } virtual ~QtRelationalReaderStringHadler() { - } virtual void startRelation(string_t name, std::vector attributes) override { - emit signal_startRelation(name, attributes); + emit startRelationReceived(name, attributes); } virtual void attribute(const string_t& value) override { - emit signal_attribute(value); + emit attributeReceived(value); }; virtual void endOfPipe() override { - emit signal_endOfPipe(); + emit endOfPipeReceived(); }; signals: - void signal_startRelation(string_t name, std::vector attributes); - void signal_attribute(const string_t& value); - void signal_endOfPipe(); - -private slots: - - // FIXME: asynchronous signal-slot data passing between two threads - - void slot_startRelation(string_t name, std::vector attributes) { - target->startRelation(name, attributes); - }; - - void slot_attribute(const string_t& value) { - target->attribute(value); - }; - - void slot_endOfPipe() { - target->endOfPipe(); - }; + void startRelationReceived(const string_t name, std::vector attributes); + void attributeReceived(const string_t value); + void endOfPipeReceived(); }; diff -r ac70c7af6a9b -r b13e7ed9eea3 src/RelpipeChartMainWindow.cpp --- a/src/RelpipeChartMainWindow.cpp Sun Sep 30 18:34:34 2018 +0200 +++ b/src/RelpipeChartMainWindow.cpp Sun Sep 30 20:54:35 2018 +0200 @@ -23,7 +23,7 @@ RelpipeChartMainWindow::~RelpipeChartMainWindow() { } -void RelpipeChartMainWindow::startRelation(string_t name, std::vector attributes) { +void RelpipeChartMainWindow::startRelation(const string_t name, std::vector attributes) { setStatusMessage(L"Reading relation: " + name); attributeCounter = 0; QSplitter* splitter = new QSplitter(Qt::Orientation::Vertical, tabs); @@ -43,7 +43,7 @@ tabs->setTabIcon(index, QIcon::fromTheme("application-vnd.oasis.opendocument.spreadsheet")); } -void RelpipeChartMainWindow::attribute(const string_t& value) { +void RelpipeChartMainWindow::attribute(const string_t value) { // TODO: draw chart integer_t column = attributeCounter % currentTable->columnCount(); integer_t row = attributeCounter / currentTable->columnCount(); diff -r ac70c7af6a9b -r b13e7ed9eea3 src/RelpipeChartMainWindow.h --- a/src/RelpipeChartMainWindow.h Sun Sep 30 18:34:34 2018 +0200 +++ b/src/RelpipeChartMainWindow.h Sun Sep 30 20:54:35 2018 +0200 @@ -13,15 +13,15 @@ using namespace relpipe::reader; using namespace relpipe::reader::handlers; -class RelpipeChartMainWindow : public QMainWindow, public RelationalReaderStringHadler { +class RelpipeChartMainWindow : public QMainWindow { Q_OBJECT public: RelpipeChartMainWindow(); virtual ~RelpipeChartMainWindow(); - virtual void startRelation(string_t name, std::vector attributes) override; - virtual void attribute(const string_t& value) override; - virtual void endOfPipe() override; public slots: + void startRelation(const string_t name, std::vector attributes); + void attribute(const string_t value); + void endOfPipe(); void setStatusMessage(string_t message); private: Ui::RelpipeChartMainWindow widget; diff -r ac70c7af6a9b -r b13e7ed9eea3 src/relpipe-out-chart.cpp --- a/src/relpipe-out-chart.cpp Sun Sep 30 18:34:34 2018 +0200 +++ b/src/relpipe-out-chart.cpp Sun Sep 30 20:54:35 2018 +0200 @@ -15,6 +15,11 @@ using namespace relpipe::cli; using namespace relpipe::reader; +// signal/slot parameters must be declared here and registered with qRegisterMetaType() + +Q_DECLARE_METATYPE(string_t) +Q_DECLARE_METATYPE(std::vector) + class RelationalReaderThread : public QThread { private: std::shared_ptr reader; @@ -48,13 +53,23 @@ RelpipeChartMainWindow window; window.show(); - QtRelationalReaderStringHadler handler(&app, &window); + RelationalReaderThread t(reader); + + // Proxy that passes calls from the background thread to the GUI thread using signal-slot mechanism: + QtRelationalReaderStringHadler handler(&t); // &t instead of handler.moveToThread(&t); // QObject::moveToThread: Cannot move objects with a parent + + // see Q_DECLARE_METATYPE above + qRegisterMetaType(); + qRegisterMetaType> (); + + QObject::connect(&handler, &QtRelationalReaderStringHadler::startRelationReceived, &window, &RelpipeChartMainWindow::startRelation, Qt::ConnectionType::QueuedConnection); + QObject::connect(&handler, &QtRelationalReaderStringHadler::attributeReceived, &window, &RelpipeChartMainWindow::attribute, Qt::ConnectionType::QueuedConnection); + QObject::connect(&handler, &QtRelationalReaderStringHadler::endOfPipeReceived, &window, &RelpipeChartMainWindow::endOfPipe, Qt::ConnectionType::QueuedConnection); + reader->addHandler(&handler); // Start background thread - RelationalReaderThread t(reader); t.start(); - // --- int qtResultCode = app.exec();