# HG changeset patch # User František Kučera # Date 1538174596 -7200 # Node ID c84042d014c90df84cc3270be36c5e33d38b924c # Parent a45d1cac365e6470f6b0ee7e683e66bff70de212 background thread for STDIN reading + proxy with signals/slots for passing data to the GUI thread diff -r a45d1cac365e -r c84042d014c9 nbproject/configurations.xml --- a/nbproject/configurations.xml Fri Sep 28 13:23:21 2018 +0200 +++ b/nbproject/configurations.xml Sat Sep 29 00:43:16 2018 +0200 @@ -60,6 +60,7 @@ projectFiles="true" root="build/Debug/src/relpipe-out-chart_autogen"> + build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_QtRelationalReaderStringHadler.cpp build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW/moc_RelpipeChartMainWindow.cpp @@ -90,9 +91,6 @@ - - @@ -102,6 +100,27 @@ ${MAKE} -f Makefile ${MAKE} -f Makefile clean build/Debug/src/relpipe-out-chart + + + build/Debug/src + src + build/Debug/src/relpipe-out-chart_autogen/include + ../relpipe-lib-reader.cpp/include + ../relpipe-lib-cli.cpp/include + /usr/include/x86_64-linux-gnu/qt5 + /usr/include/x86_64-linux-gnu/qt5/QtWidgets + /usr/include/x86_64-linux-gnu/qt5/QtGui + /usr/include/x86_64-linux-gnu/qt5/QtCore + /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ + /usr/include/x86_64-linux-gnu/qt5/QtCharts + + + QT_CHARTS_LIB + QT_CORE_LIB + QT_GUI_LIB + QT_WIDGETS_LIB + + build/Debug @@ -113,8 +132,11 @@ ex="false" tool="1" flavor2="11"> - - + + - + - build/Debug/src - src - build/Debug/src/relpipe-out-chart_autogen/include - ../relpipe-lib-reader.cpp/include - ../relpipe-lib-cli.cpp/include - /usr/include/x86_64-linux-gnu/qt5 - /usr/include/x86_64-linux-gnu/qt5/QtWidgets - /usr/include/x86_64-linux-gnu/qt5/QtGui - /usr/include/x86_64-linux-gnu/qt5/QtCore - /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ - /usr/include/x86_64-linux-gnu/qt5/QtCharts /usr/include - - QT_CHARTS_LIB - QT_CORE_LIB - QT_GUI_LIB - QT_WIDGETS_LIB - - - - - - - build/Debug/src/relpipe-out-chart_autogen/EWIEGA46WW - /usr/include/x86_64-linux-gnu/qt5/QtCore - /usr/include/x86_64-linux-gnu/qt5/QtGui - /usr/include/x86_64-linux-gnu/qt5/QtWidgets - build/Debug/src/relpipe-out-chart_autogen/include - src - build/Debug/src/relpipe-out-chart_autogen - /usr/include/x86_64-linux-gnu/qt5 - build/Debug/src - - - build/Debug/src - src - build/Debug/src/relpipe-out-chart_autogen/include - ../relpipe-lib-reader.cpp/include - ../relpipe-lib-cli.cpp/include - /usr/include/x86_64-linux-gnu/qt5 - /usr/include/x86_64-linux-gnu/qt5/QtWidgets - /usr/include/x86_64-linux-gnu/qt5/QtGui - /usr/include/x86_64-linux-gnu/qt5/QtCore - /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ - /usr/include/x86_64-linux-gnu/qt5/QtCharts - - - QT_CHARTS_LIB - QT_CORE_LIB - QT_GUI_LIB - QT_WIDGETS_LIB - - - - ../relpipe-lib-cli.cpp/include/relpipe/cli - src - /usr/include/x86_64-linux-gnu/qt5/QtCore - /usr/include/x86_64-linux-gnu/qt5/QtGui - /usr/include/x86_64-linux-gnu/qt5/QtWidgets - ../relpipe-lib-reader.cpp/include/relpipe/reader - ../relpipe-lib-reader.cpp/include/relpipe/reader/handlers - build/Debug/src/relpipe-out-chart_autogen/include - ../relpipe-lib-cli.cpp/include - ../relpipe-lib-reader.cpp/include - /usr/include/x86_64-linux-gnu/qt5 - build/Debug/src - + diff -r a45d1cac365e -r c84042d014c9 src/CMakeLists.txt --- a/src/CMakeLists.txt Fri Sep 28 13:23:21 2018 +0200 +++ b/src/CMakeLists.txt Sat Sep 29 00:43:16 2018 +0200 @@ -21,6 +21,7 @@ # Executable output: add_executable( ${EXECUTABLE_FILE} + QtRelationalReaderStringHadler.h # QObjects must be listed here (including them from other files is not enough) RelpipeChartMainWindow.ui RelpipeChartMainWindow.cpp relpipe-out-chart.cpp diff -r a45d1cac365e -r c84042d014c9 src/QtRelationalReaderStringHadler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/QtRelationalReaderStringHadler.h Sat Sep 29 00:43:16 2018 +0200 @@ -0,0 +1,70 @@ +#pragma once + +#include + +#include +#include +#include +#include + +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); + } + + virtual ~QtRelationalReaderStringHadler() { + + } + + virtual void startRelation(string_t name, std::vector attributes) override { + emit signal_startRelation(name, attributes); + } + + virtual void attribute(const string_t& value) override { + emit signal_attribute(value); + }; + + virtual void endOfPipe() override { + emit signal_endOfPipe(); + }; + +signals: + void signal_startRelation(string_t name, std::vector attributes); + void signal_attribute(const string_t& value); + void signal_endOfPipe(); + +private slots: + + 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(); + }; +}; diff -r a45d1cac365e -r c84042d014c9 src/RelpipeChartMainWindow.cpp --- a/src/RelpipeChartMainWindow.cpp Fri Sep 28 13:23:21 2018 +0200 +++ b/src/RelpipeChartMainWindow.cpp Sat Sep 29 00:43:16 2018 +0200 @@ -6,20 +6,25 @@ #include "RelpipeChartMainWindow.h" +using namespace relpipe::reader; +using namespace relpipe::reader::handlers; + RelpipeChartMainWindow::RelpipeChartMainWindow() { widget.setupUi(this); - QTabWidget* tabs = new QTabWidget(this); + tabs->addTab(new QPushButton("here will be options", tabs), "Options"); + + statusBar()->addWidget(new QLabel("Loading relations...", widget.statusbar)); + - for (int i = 0; i < 5; i++) { - QSplitter* splitter = new QSplitter(Qt::Orientation::Vertical, tabs); - splitter->addWidget(new QPushButton("here will be the chart", splitter)); - splitter->addWidget(new QPushButton("here will be the table", splitter)); - tabs->addTab(splitter, "relation_name"); - } - - //statusBar()->addWidget(new QPushButton("xxx", widget.statusbar)); - statusBar()->addWidget(new QLabel("Loading relations...", widget.statusbar)); + // TODO: remove; just demo + QPushButton* emitButton = new QPushButton("emit", widget.statusbar); + statusBar()->addWidget(emitButton); + QObject::connect( + emitButton, &QPushButton::pressed, + this, &RelpipeChartMainWindow::slot123 + ); + // --- setCentralWidget(tabs); @@ -27,3 +32,25 @@ RelpipeChartMainWindow::~RelpipeChartMainWindow() { } + +void RelpipeChartMainWindow::slot123() { + // TODO: remove; just demo + statusBar()->addWidget(new QPushButton("slot123", widget.statusbar)); +} + +void RelpipeChartMainWindow::startRelation(string_t name, std::vector attributes) { + // TODO: chart and table + QSplitter* splitter = new QSplitter(Qt::Orientation::Vertical, tabs); + splitter->addWidget(new QPushButton("here will be the chart", splitter)); + splitter->addWidget(new QPushButton("here will be the table", splitter)); + tabs->addTab(splitter, QString::fromWCharArray(name.c_str())); +} + +void RelpipeChartMainWindow::attribute(const string_t& value) { + // TODO: fill table and draw chart +} + +void RelpipeChartMainWindow::endOfPipe() { + // TODO: just display a message + statusBar()->addWidget(new QPushButton("endOfPipe", widget.statusbar)); +} diff -r a45d1cac365e -r c84042d014c9 src/RelpipeChartMainWindow.h --- a/src/RelpipeChartMainWindow.h Fri Sep 28 13:23:21 2018 +0200 +++ b/src/RelpipeChartMainWindow.h Sat Sep 29 00:43:16 2018 +0200 @@ -2,11 +2,27 @@ #include "ui_RelpipeChartMainWindow.h" -class RelpipeChartMainWindow : public QMainWindow { +#include +#include +#include +#include + +using namespace relpipe::reader; +using namespace relpipe::reader::handlers; + +class RelpipeChartMainWindow : public QMainWindow, public RelationalReaderStringHadler { 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; private: Ui::RelpipeChartMainWindow widget; + QTabWidget* tabs = new QTabWidget(this); +public slots: + void slot123(); +signals: + void signal123(); }; diff -r a45d1cac365e -r c84042d014c9 src/relpipe-out-chart.cpp --- a/src/relpipe-out-chart.cpp Fri Sep 28 13:23:21 2018 +0200 +++ b/src/relpipe-out-chart.cpp Sat Sep 29 00:43:16 2018 +0200 @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -9,24 +10,60 @@ #include #include "RelpipeChartMainWindow.h" +#include "QtRelationalReaderStringHadler.h" using namespace relpipe::cli; using namespace relpipe::reader; +class WorkerThread : public QThread { +private: + std::shared_ptr reader; +public: + + // TODO: better background thread; lambda? + + WorkerThread(std::shared_ptr reader) : + reader(reader) { + } + + void run() { + try { + reader->process(); + } catch (RelpipeReaderException& e) { + // TODO: handle exception, show error dialog + } + } +}; + int main(int argc, char**argv) { CLI cli(argc, argv); // TODO: argument name collisions? Filter arguments? Use prefix for Qt? Qt: -title, -style, -geometry QApplication app(argc, argv); - + std::cout << "TODO: relpipe-out-chart..." << std::endl; - + std::shared_ptr reader(Factory::create(std::cin)); + int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR; - + RelpipeChartMainWindow window; + + // TODO: remove; just demo + QObject::connect(&window, &RelpipeChartMainWindow::signal123, &window, &RelpipeChartMainWindow::slot123); + window.show(); - + + QtRelationalReaderStringHadler handler(&app, &window); + reader->addHandler(&handler); + + // Start background thread + WorkerThread t(reader); + t.start(); + // --- + + // window.signal123(); + app.exec(); //return app.exec();