系统架构工作笔记-数据展示进程与读取数据进程分离,实现低耦合(展示软件可适用任意厂家数据库)
目錄
?
背景
實踐環(huán)境
邏輯結(jié)構(gòu)圖
運行截圖
數(shù)據(jù)展示進(jìn)程源碼
服務(wù)進(jìn)程(插件調(diào)用)源碼
插件源碼
MySQL相關(guān)
?
背景
工作一年零1個月了(加上實習(xí)),靠著工作中學(xué)到的東西,花了周末2天時間,做了一個小系統(tǒng),這個小系統(tǒng)中有2個進(jìn)程,一個是用于數(shù)據(jù)展示的進(jìn)程。
另外一個進(jìn)程是用來調(diào)取Qt插件,這個插件可能連接了Mysql,也可能連接了SQLSever等數(shù)據(jù)庫,調(diào)用插件后,讀取插件返回的數(shù)據(jù)庫的數(shù)據(jù);
展示軟件通過設(shè)置一個描述字符串,這個字符串可以是檢索Mysql的語句!
把展示軟件的描述字符串內(nèi)容和這個字符串的ID,通過共享內(nèi)存的方式給插件調(diào)用端,插件調(diào)用端是一個中轉(zhuǎn),把數(shù)據(jù)給對應(yīng)的插件。獲得了數(shù)據(jù)后!
再使用共享內(nèi)存的方式給數(shù)據(jù)展示進(jìn)程!
?
實踐環(huán)境
語言有C++,和SQL,
其中C++使用Qt框架(Qt Creator 5.7作為IDE,編譯器為MinGw)
數(shù)據(jù)庫使用的是Mysql數(shù)據(jù)庫;
?
?
邏輯結(jié)構(gòu)圖
所以本次實踐涉及3個程序,一個是數(shù)據(jù)展示進(jìn)程,一個是服務(wù)進(jìn)程(提供展示數(shù)據(jù)),一個是插件
?
運行截圖
話不多說,先看動態(tài)演示!
添加很多展示數(shù)據(jù)后!
拖動動態(tài)數(shù)據(jù):
設(shè)置描述符后:
上面設(shè)置的描述符為:
select value from sourcenetload.datasample where idval=6以上的數(shù)據(jù)都是從數(shù)據(jù)庫中讀取的!
這里數(shù)據(jù)改變的原因是,我在Mysql中寫了一個存儲過程,這個存儲過程能修改表中所有數(shù)據(jù),
用寫了一個事件,每秒進(jìn)行調(diào)用,下面將會詳細(xì)給出!
?
服務(wù)進(jìn)程中轉(zhuǎn)站截圖:
插件端
?
?
數(shù)據(jù)展示進(jìn)程源碼
程序結(jié)構(gòu)如下:
dynamicdata.h
#ifndef DYNAMICDATA_H #define DYNAMICDATA_H#include <QGraphicsItem>class DynamicData : public QGraphicsItem { public:DynamicData();~DynamicData();QRectF boundingRect()const Q_DECL_OVERRIDE;void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE;int getId();void setId(const int &id);QString getText();void setText(const QString &str);QString getDescrib();void setDescrib(const QString &str);private:int m_id;QString m_text;QString m_describ; };#endif // DYNAMICDATA_Hmygraphicsscene.h
#ifndef MYGRAPHICSSCENE_H #define MYGRAPHICSSCENE_H#include <QObject> #include <QPointF> #include <QGraphicsView>class MyGraphicsScene : public QGraphicsScene {Q_OBJECT public:MyGraphicsScene(QWidget *parent = 0);~MyGraphicsScene();void createDynamicData(const QPointF &pt, const int &id);protected:void dragEnterEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE;void dropEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE;void dragMoveEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE;void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); };#endif // MYGRAPHICSSCENE_Hmygraphicsview.h
#ifndef MYGRAPHICSVIEW_H #define MYGRAPHICSVIEW_H#include <QObject> #include <QGraphicsView>class MyGraphicsView : public QGraphicsView {Q_OBJECT public:MyGraphicsView(QWidget *parent = 0);~MyGraphicsView();protected:void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;private:int m_count; };#endif // MYGRAPHICSVIEW_Hmylistwidget.h
#ifndef MYLISTWIDGET_H #define MYLISTWIDGET_H#include <QObject> #include <QListWidget>class MyListWidget : public QListWidget {Q_OBJECT public:MyListWidget(QWidget *parent = 0);~MyListWidget();protected:void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;private:QPoint m_dragPosition;QListWidgetItem *m_dragItem; };#endif // MYLISTWIDGET_Hsetdatadialog.h
#ifndef SETDATADIALOG_H #define SETDATADIALOG_H#include <QDialog>namespace Ui { class setDataDialog; }class setDataDialog : public QDialog {Q_OBJECTpublic:explicit setDataDialog(QWidget *parent = 0, const int &id = -1, const QString &str = "NULL");~setDataDialog();QString getDescrib();protected slots:void okBtnClicked();void cancelBtnClicked();private:Ui::setDataDialog *ui; };#endif // SETDATADIALOG_Hwidget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE class QSharedMemory; class QTimer; QT_END_NAMESPACEnamespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();protected slots:void shareMemoryTimeout();private:Ui::Widget *ui;QSharedMemory *m_sharedMemory;QSharedMemory *m_sharedMemory2;QTimer *m_timer; };#endif // WIDGET_Hdynamicdata.cpp
#include "dynamicdata.h" #include <QPainter> #include <QDebug> #include <QBrush> #include <QMessageBox>DynamicData::DynamicData() {m_text = "-123456789";m_describ = "NULL"; }DynamicData::~DynamicData() {}QRectF DynamicData::boundingRect() const {qreal penWidth = 1;return QRectF(0 - penWidth / 2, 0 - penWidth / 2, 80 + penWidth, 10 + penWidth); }void DynamicData::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {Q_UNUSED(option)Q_UNUSED(widget)painter->setBrush(Qt::red);painter->drawText(0, 0, 80, 10, Qt::AlignCenter, m_text); }int DynamicData::getId() {return m_id; }void DynamicData::setId(const int &id) {m_id = id; }QString DynamicData::getText() {return m_text; }void DynamicData::setText(const QString &str) {m_text = str;update(); }QString DynamicData::getDescrib() {return m_describ; }void DynamicData::setDescrib(const QString &str) {m_describ = str; }main.cpp
#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }mygraphicsscene.cpp
#include "mygraphicsscene.h" #include "dynamicdata.h" #include "setdatadialog.h" #include <QDebug> #include <QMimeData> #include <QPen> #include <QMessageBox> #include <QGraphicsSceneDragDropEvent> #include <QDragEnterEvent> #include <QDropEvent> #include <QTransform> #include <QDragMoveEvent>MyGraphicsScene::MyGraphicsScene(QWidget *parent) : QGraphicsScene(parent) {}MyGraphicsScene::~MyGraphicsScene() {}void MyGraphicsScene::createDynamicData(const QPointF &pt, const int &id) {DynamicData *item = new DynamicData;item->setPos(pt);item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);item->setId(id);addItem(item); }void MyGraphicsScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) {if(event->mimeData()->hasFormat("text/plain")){event->acceptProposedAction();} }void MyGraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event) {QGraphicsScene::dropEvent(event); }void MyGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) {event->accept(); }void MyGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {QTransform deviceTransform;DynamicData* item = static_cast<DynamicData*>(itemAt(event->scenePos(), deviceTransform));if(item != NULL){setDataDialog *msetDataDialog = new setDataDialog(NULL, item->getId(), item->getDescrib());if(msetDataDialog->exec() == QDialog::Accepted){item->setDescrib(msetDataDialog->getDescrib());}delete msetDataDialog;}QGraphicsScene::mousePressEvent(event); }mygraphicsview.cpp
#include "mygraphicsview.h" #include "mygraphicsscene.h" #include <QDragEnterEvent> #include <QDropEvent> #include <QMimeData> #include <QDebug>MyGraphicsView::MyGraphicsView(QWidget *parent) : QGraphicsView(parent) {MyGraphicsScene *scene = new MyGraphicsScene;scene->setSceneRect(-1000, -1000, 1000, 1000);setScene(scene);m_count = 0; }MyGraphicsView::~MyGraphicsView() {}void MyGraphicsView::dragEnterEvent(QDragEnterEvent *event) {if(event->mimeData()->hasFormat("text/plain")){event->acceptProposedAction();}QGraphicsView::dragEnterEvent(event); }void MyGraphicsView::dropEvent(QDropEvent *event) {if(event->mimeData()->hasFormat("text/plain")){MyGraphicsScene *scene = (MyGraphicsScene*)this->scene();scene->createDynamicData(mapToScene(event->pos()), m_count++);event->acceptProposedAction();}QGraphicsView::dropEvent(event); }mylistwidget.cpp
#include "mylistwidget.h" #include <QMouseEvent> #include <QListWidgetItem> #include <QDrag> #include <QMimeData> #include <QPainter> #include <QApplication> #include <QPixmap>MyListWidget::MyListWidget(QWidget *parent) : QListWidget(parent) {}MyListWidget::~MyListWidget() {}void MyListWidget::mouseMoveEvent(QMouseEvent *event) {if(!(event->buttons() & Qt::LeftButton))return;if((event->pos() - m_dragPosition).manhattanLength() < QApplication::startDragDistance())return;if(!m_dragItem)return;QDrag *drag = new QDrag(this);QMimeData *mimeData = new QMimeData;mimeData->setText(currentItem()->text());drag->setMimeData(mimeData);if(mimeData->text() == "動態(tài)數(shù)據(jù)"){QPixmap dragImg(100, 50);QPainter painter(&dragImg);painter.setBrush(QBrush(Qt::red));painter.drawRect(0, 0, 100, 50);drag->setPixmap(dragImg);}drag->exec(Qt::CopyAction|Qt::MoveAction); }void MyListWidget::mousePressEvent(QMouseEvent *event) {m_dragPosition=event->pos();m_dragItem=this->itemAt(event->pos());QListWidget::mousePressEvent(event);}setdatadialog.cpp
#include "setdatadialog.h" #include "ui_setdatadialog.h"setDataDialog::setDataDialog(QWidget *parent, const int &id, const QString &str) :QDialog(parent),ui(new Ui::setDataDialog) {ui->setupUi(this);this->setWindowTitle("CSDN IT1995設(shè)置描述符號");ui->idLineEdit->setText(QString::number(id));ui->idLineEdit->setEnabled(false);ui->describLineEdit->setText(str);connect(ui->okPushButton, SIGNAL(clicked(bool)), this, SLOT(okBtnClicked()));connect(ui->cancelPushButton, SIGNAL(clicked(bool)), this, SLOT(cancelBtnClicked())); }setDataDialog::~setDataDialog() {delete ui; }QString setDataDialog::getDescrib() {return ui->describLineEdit->text(); }void setDataDialog::okBtnClicked() {accept(); }void setDataDialog::cancelBtnClicked() {reject(); }widget.cpp
#include "widget.h" #include "ui_widget.h" #include "dynamicdata.h" #include <QSharedMemory> #include <QGraphicsItem> #include <QTImer> #include <QDebug> #include <QDataStream> #include <QBuffer>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);this->setWindowTitle("CSDN IT1995");ui->listWidget->insertItem(0, "動態(tài)數(shù)據(jù)");m_sharedMemory = new QSharedMemory("CSDN IT1995");m_sharedMemory2 = new QSharedMemory(this);m_sharedMemory2->setKey("5991TI NDSC");m_timer = new QTimer(this);connect(m_timer, SIGNAL(timeout()), this, SLOT(shareMemoryTimeout()));m_timer->start(500); }Widget::~Widget() {delete ui; }//這里我偷懶了,應(yīng)該要抽2-3個函數(shù)出來的。 void Widget::shareMemoryTimeout() {//偷懶了QList<QGraphicsItem *> list = ui->graphicsView->items();if(list.isEmpty())return;if(m_sharedMemory->isAttached()){if(!m_sharedMemory->detach()){return;}}QString str;foreach(QGraphicsItem *item, list){int id = static_cast<DynamicData*>(item)->getId();QString describ = static_cast<DynamicData*>(item)->getDescrib();str.append(QString::number(id) + ";" + describ + "#");}str = str.left(str.length() - 1);QBuffer buffer;buffer.open(QBuffer::ReadWrite);QDataStream out(&buffer);out << str;if(!m_sharedMemory->create(buffer.size())){qDebug() << "create failed!";return;}m_sharedMemory->lock();char *to = static_cast<char*>(m_sharedMemory->data());memcpy(to, str.toStdString().c_str(), (int)buffer.size());m_sharedMemory->unlock();//獲取數(shù)據(jù) 偷懶了if(!m_sharedMemory2->attach()){return;}QBuffer buffer2;m_sharedMemory2->lock();buffer2.setData((char*)m_sharedMemory2->constData(), m_sharedMemory2->size());buffer2.open(QBuffer::ReadOnly);QString data2 = buffer2.readAll();m_sharedMemory2->unlock();m_sharedMemory2->detach();//設(shè)置item的值 偷懶了QStringList listData = data2.split("#");listData.removeLast();qDebug() << listData;for(int i = 0; i < listData.size(); i++){QStringList idList = listData[i].split(";");foreach(QGraphicsItem *item, list){int id = static_cast<DynamicData*>(item)->getId();if(id == idList[0].toInt()){static_cast<DynamicData*>(item)->setText(idList[1]);ui->graphicsView->update();}}} }setdatadialog.ui
widget.ui
?
服務(wù)進(jìn)程(插件調(diào)用)源碼
程序結(jié)構(gòu)如下:
appinterface.h
#ifndef APPINTERFACE_H #define APPINTERFACE_H#include <QObject>class AppInterface{public:virtual ~AppInterface(){}virtual QString name() = 0;virtual QWidget *widget() = 0;virtual void setSQLData(const QString &cmdData){ Q_UNUSED(cmdData); }virtual QString getSQLData(){ return""; }QString libDir(){return m_libDir.isEmpty() ? "./" : m_libDir;}void setLibDir(const QString &libDir){m_libDir = libDir;}private:QString m_libDir;};QT_BEGIN_NAMESPACE#define Interface_iid "com.IT1995.Interface" Q_DECLARE_INTERFACE(AppInterface, Interface_iid)QT_END_NAMESPACE#endif // APPINTERFACE_Hwidget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMap>namespace Ui { class Widget; }QT_BEGIN_NAMESPACE class QSharedMemory; QT_END_NAMESPACEclass AppInterface;class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);void readPlugin();~Widget();protected:void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;void setMap(const QString &data);private:Ui::Widget *ui;QSharedMemory *m_sharedMemory;QSharedMemory *m_sharedMemory2;int m_timerId;int m_timerId2;QMap<int, QString> m_map;QList<AppInterface*> m_widgetList;QString m_sendMsg; };#endif // WIDGET_Hmain.cpp
#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }widget.cpp
#include "widget.h" #include "ui_widget.h" #include "appinterface.h" #include <QDir> #include <QPluginLoader> #include <QMessageBox> #include <QSharedMemory> #include <QDebug> #include <QDataStream> #include <QBuffer>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);this->setWindowTitle("CSDN IT1995中轉(zhuǎn)站");m_sharedMemory = new QSharedMemory(this);m_sharedMemory2 = new QSharedMemory(this);m_sharedMemory->setKey("CSDN IT1995");m_sharedMemory2->setKey("5991TI NDSC");m_timerId = startTimer(500);m_timerId2 = startTimer(500);m_sendMsg = "";readPlugin(); }void Widget::readPlugin() {QDir pluginsDir(qApp->applicationDirPath() + "/plugin");foreach(QString filename, pluginsDir.entryList(QDir::Files)){QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(filename));QObject *plugin = pluginLoader.instance();if(plugin){AppInterface *app = qobject_cast<AppInterface*>(plugin);if(app){m_widgetList.append(app);}}}if(m_widgetList.isEmpty()){QMessageBox::warning(this, "warning", "load plugin error");}else{foreach(AppInterface *w, m_widgetList){w->widget();qDebug() << w->name();}} }Widget::~Widget() {delete ui; }void Widget::timerEvent(QTimerEvent *event) {if(event->timerId() == m_timerId2){QBuffer buffer;buffer.open(QBuffer::ReadWrite);QDataStream out(&buffer);out << m_sendMsg;if(!m_sharedMemory2->create(buffer.size())){qDebug() << "create failed!";return;}m_sharedMemory2->lock();char *to = static_cast<char*>(m_sharedMemory2->data());memcpy(to, m_sendMsg.toStdString().c_str(), (int)buffer.size());m_sharedMemory2->unlock();}else if(event->timerId() == m_timerId){if(!m_sharedMemory->attach()){return;}QBuffer buffer;m_sharedMemory->lock();buffer.setData((char*)m_sharedMemory->constData(), m_sharedMemory->size());buffer.open(QBuffer::ReadOnly);QString data = buffer.readAll();m_sharedMemory->unlock();m_sharedMemory->detach();setMap(data);//qDebug() << data;//獲取數(shù)據(jù)m_sendMsg.clear();foreach(AppInterface *w, m_widgetList){QList<int> mapList = m_map.keys();for(int i = 0; i < mapList.size(); i++){w->setSQLData(m_map.value(mapList[i]));m_sendMsg.append(QString::number(mapList[i]) + ";" + w->getSQLData() + "#");}}m_sendMsg.left(m_sendMsg.size() - 1);qDebug() << m_sendMsg;} }void Widget::setMap(const QString &data) {QStringList list = data.split("#");for(int i = 0; i < list.size(); i++){QStringList singleList = list[i].split(";");m_map.insert(singleList[0].toInt(), singleList[1]);} }widget.ui
?
插件源碼
程序結(jié)構(gòu)如下:
這個插件主要是用于讀取Mysql
appinterface.h
#ifndef APPINTERFACE_H #define APPINTERFACE_H#include <QObject>class AppInterface{public:virtual ~AppInterface(){}virtual QString name() = 0;virtual QWidget *widget() = 0;virtual void setSQLData(const QString &cmdData){ Q_UNUSED(cmdData); }virtual QString getSQLData(){ return""; }QString libDir(){return m_libDir.isEmpty() ? "./" : m_libDir;}void setLibDir(const QString &libDir){m_libDir = libDir;}private:QString m_libDir;};QT_BEGIN_NAMESPACE#define Interface_iid "com.IT1995.Interface" Q_DECLARE_INTERFACE(AppInterface, Interface_iid)QT_END_NAMESPACE#endif // APPINTERFACE_Hwidget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QSqlDatabase>namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);void setData(const QString &cmdData);QString getData();~Widget();protected:bool connectMySQL();QString getSqlData(const QString &cmd);private:Ui::Widget *ui;QSqlDatabase m_db;QString m_cmd; };#endif // WIDGET_Hwidgetplugin.h
#ifndef WIDGETPLUGIN_H #define WIDGETPLUGIN_H#include <QObject> #include "appinterface.h" #include "widget.h"class WidgetPlugin : public QObject, AppInterface {Q_OBJECTQ_PLUGIN_METADATA(IID "com.IT1995.Interface")Q_INTERFACES(AppInterface)public:QString name(){ return QStringLiteral("MySQL插件");}QWidget *widget(){m_widget = new Widget();return m_widget;}void setSQLData(const QString &cmdData){m_widget->setData(cmdData);}virtual QString getSQLData(){return m_widget->getData();}private:Widget *m_widget; };#endif // WIDGETPLUGIN_Hmain.cpp
#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QMessageBox> #include <QSqlQuery>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);if(!connectMySQL()){//QMessageBox::information(this, "tip", "連接Mysql數(shù)據(jù)庫失敗");return;}//QMessageBox::information(this, "tip", "連接Mysql數(shù)據(jù)庫成功"); }void Widget::setData(const QString &cmdData) {m_cmd = cmdData; }QString Widget::getData() {return getSqlData(m_cmd); }Widget::~Widget() {delete ui; }bool Widget::connectMySQL() {m_db = QSqlDatabase::addDatabase("QMYSQL");m_db.setHostName("127.0.0.1");m_db.setPort(3306);m_db.setDatabaseName("mysql");m_db.setUserName("root");m_db.setPassword("root");if(!m_db.open()){qDebug() << "error";return false;}return true; }QString Widget::getSqlData(const QString &cmd) {QSqlQuery query;if(!query.exec(cmd) || query.size() <= 0){return "-1234567890";}while(query.next()){//理論只有一條return query.value(0).toString();}return "-1234567890"; }widget.ui
這個ui里面沒東西
?
MySQL相關(guān)
mysql存儲過程,表結(jié)構(gòu),事件已經(jīng)在下面的博文中給出了,在此不再詳細(xì)說明:
MySQL工作筆記-使用事件和存儲過程定時更新某表數(shù)據(jù)
https://blog.csdn.net/qq78442761/article/details/88597665
總結(jié)
以上是生活随笔為你收集整理的系统架构工作笔记-数据展示进程与读取数据进程分离,实现低耦合(展示软件可适用任意厂家数据库)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt笔记-QWebView完整加载页面及
- 下一篇: Java工作笔记-对反射的进一步理解