better use of signal/slot mechanism, threads, Qt::ConnectionType::QueuedConnection
--- 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)
--- 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<AttributeMetadata>)
-
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<string_t>();
- qRegisterMetaType<std::vector < AttributeMetadata >> ();
-
- 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<AttributeMetadata> 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<AttributeMetadata> 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<AttributeMetadata> 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<AttributeMetadata> attributes);
+ void attributeReceived(const string_t value);
+ void endOfPipeReceived();
};
--- 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<AttributeMetadata> attributes) {
+void RelpipeChartMainWindow::startRelation(const string_t name, std::vector<AttributeMetadata> 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();
--- 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<AttributeMetadata> attributes) override;
- virtual void attribute(const string_t& value) override;
- virtual void endOfPipe() override;
public slots:
+ void startRelation(const string_t name, std::vector<AttributeMetadata> attributes);
+ void attribute(const string_t value);
+ void endOfPipe();
void setStatusMessage(string_t message);
private:
Ui::RelpipeChartMainWindow widget;
--- 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<AttributeMetadata>)
+
class RelationalReaderThread : public QThread {
private:
std::shared_ptr<RelationalReader> 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<string_t>();
+ qRegisterMetaType<std::vector < AttributeMetadata >> ();
+
+ 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();