better use of signal/slot mechanism, threads, Qt::ConnectionType::QueuedConnection v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sun, 30 Sep 2018 20:54:35 +0200
branchv_0
changeset 20 b13e7ed9eea3
parent 19 ac70c7af6a9b
child 21 a05fa65d47de
better use of signal/slot mechanism, threads, Qt::ConnectionType::QueuedConnection
.hgignore
src/QtRelationalReaderStringHadler.h
src/RelpipeChartMainWindow.cpp
src/RelpipeChartMainWindow.h
src/relpipe-out-chart.cpp
--- 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();