Кросплатформовий клієнт-серверний додаток для віддаленого моніторингу та управління персональним комп’ютером — TDM

Специфіка діяльності систем віддаленого моніторингу та управління комп'ютером. Технології розробки систем моніторингу і управління та різноманітність мов програмування. Аналіз предметної області, структури додатку. Робота с XML, JSON та WebSocket.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык украинский
Дата добавления 08.06.2015
Размер файла 2,9 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

templateParent->show ();

QDomDocument xml ("content");

xml. setContent (content);

auto root = xml. documentElement ();

QString bodyStyle = root. attribute ("style");

templateParent->setStyleSheet ("QWidget#mainWidget {" + bodyStyle + "}");

auto elements = root. childNodes ();

auto panelY = 0;

for (int i = 0; i < elements. count (); i++) {

auto element = elements. at (i). toElement ();

auto name = element. nodeName ();

if (name == "panel") {

QString margin = element. attribute ("margin");

QString padding = element. attribute ("padding");

QString style = element. attribute ("style");

QString align = element. attribute ("align");

QString bottom = element. attribute ("bottom");

QString top = element. attribute ("top");

int panelHeight = 0;

Panel* panel = new Panel (templateParent);

panel->setMargin (margin. toInt ());

panel->addStyle (style);

if (align == "center")

panel->setAlignment (Qt:: AlignCenter);

else if (align == "right") {

panel->setAlignment (Qt:: AlignRight);

} else {

panel->setAlignment (Qt:: AlignLeft);

}

panel->setProperty ("padding", padding);

panel->setFixedWidth (this->width () - margin. toInt () * 2);

panel->move (margin. toInt (), panelY + margin. toInt ());

if (bottom! = "") panel->move (panel->x (), height () - bottom. toInt ());

if (top! = "") panel->move (panel->x (), top. toInt ());

int lineY = padding. toInt ();

auto lines = element. childNodes ();

for (int j = 0; j < lines. count (); j++) {

auto _el = lines. at (j). toElement ();

auto _name = _el. nodeName ();

if (_name == "line") {

QString tsize = _el. attribute ("tsize");

QString tcolor = _el. attribute ("tcolor");

QString style = _el. attribute ("style");

int lineWidth = 0;

int lineHeight = tsize. toInt () + 5;

QLabel* line = new QLabel (panel);

line->setStyleSheet (style);

line->setAttribute (Qt:: WA_TranslucentBackground);

int textX = 0;

auto texts = _el. childNodes ();

for (int o = 0; o < texts. count (); o++) {

auto _text = texts. at (o). toElement ();

auto _elName = _text. nodeName ();

if (_elName == "text") {

QString id = _text. attribute ("id");

QString color = _text. attribute ("color");

QString log = _text. attribute ("log");

bool bold = (_text. attribute ("bold") == "true"? true: false);

QString stylesheet = "font-size: " + tsize + "px; color: black; ";

if (bold) stylesheet += "font-weight: bold; ";

if (! tcolor. isEmpty ()) stylesheet += "color: " + tcolor + "; ";

if (! color. isEmpty ()) stylesheet += "color: " + color + "; ";

QString value = _text. text ();

QString command;

if (value. mid (0, 1) == "{" && value. mid (value. length () - 1, 1) == "}") {

command = value. mid (1, value. length () - 2);

value = "?";

}

QLabel* text = new QLabel (line);

text->setText (value);

text->setStyleSheet (stylesheet);

text->setAttribute (Qt:: WA_TranslucentBackground);

text->setFixedHeight (tsize. toInt () + 5);

text->move (textX, 0);

text->setProperty ("log", log);

text->show ();

if (id! = "" && command! = "") {

QMap<QLabel*, QString> temp;

temp. insert (text, command);

values. insert (id, temp);

}

lineWidth += text->width ();

textX += text->width ();

}

if (_elName == "button") {

QString click = _text. attribute ("click");

QString style = _text. attribute ("style");

QString width = _text. attribute ("width");

bool bold = (_text. attribute ("bold") == "true"? true: false);

QString stylesheet = "font-size: " + QString:: number (tsize. toInt () - 10) + "px; ";

if (bold) stylesheet += "font-weight: bold; ";

QString value = _text. text ();

QPushButton* button = new QPushButton (line);

button->setText (value);

button->setStyleSheet (stylesheet + style);

button->adjustSize ();

button->setFixedHeight (tsize. toInt () + 5);

button->move (textX, 0);

button->show ();

if (! width. isEmpty ()) button->setFixedWidth (width. toInt ());

connect (button, SIGNAL (clicked ()), this, SLOT (buttonClicked ()));

if (click! = "") buttons [button] = click;

lineWidth += button->width ();

textX += button->width ();

}

if (_elName == "select") {

QString style = _text. attribute ("style");

QString width = _text. attribute ("width");

width = (width. isEmpty ()?"100": width);

QString stylesheet = "font-size: " + QString:: number (tsize. toInt () - 10) + "px; ";

QString itemsStyle = "QComboBox QAbstractItemView:: item { padding: 10px; text-align: center; border: 0; padding-left: 10px; outline: none; } QComboBox QAbstractItemView:: item: hover { outline: none; border: 0; }";

QComboBox* select = new QComboBox (line);

select->setStyleSheet ("QComboxBox { " + stylesheet + style + "} " + itemsStyle);

select->setFixedHeight (tsize. toInt () + 5);

select->installEventFilter (this);

select->setEditable (false);

select->move (textX, 0);

select->show ();

connect (select, SIGNAL (currentIndexChanged (int)), this, SLOT (selectClicked (int)));

QStyledItemDelegate* itemDelegate = new QStyledItemDelegate ();

select->setItemDelegate (itemDelegate);

if (! width. isEmpty ()) select->setFixedWidth (width. toInt ());

QMap<int, QString> temp;

auto items = _text. childNodes ();

for (int i = 0; i < items. count (); i++) {

auto item = items. at (i). toElement ();

if (item. nodeName ()! = "item") continue;

temp. insert (i, item. attribute ("execute"));

select->addItem (item. text ());

}

select->setCurrentIndex (-1);

commands. insert (select, temp);

lineWidth += select->width ();

textX += select->width ();

}

if (_elName == "graph") {

QString color = _text. attribute ("color");

QString linesize = _text. attribute ("line");

QString width = _text. attribute ("width");

QString valuesCount = _text. attribute ("values");

QString fill = _text. attribute ("fill");

QString fillColor = _text. attribute ("fillcolor");

QString gridColor = _text. attribute ("gridcolor");

if (linesize. isEmpty ()) {

QMessageBox:: information (this, "Ошибка", "Вы не указали толщину линии в шаблоне.", QMessageBox:: Ok);

qApp->exit ();

}

if (width. isEmpty ()) {

QMessageBox:: information (this, "Ошибка", "Вы не указали ширину графика в шаблоне.", QMessageBox:: Ok);

qApp->exit ();

}

valuesCount = (valuesCount. isEmpty ()?"20": valuesCount);

color = (color. isEmpty ()?"black": color);

linesize = (linesize. isEmpty ()?"!": linesize);

width = (width. isEmpty ()?"400": width);

QGraphicsView* graph = new QGraphicsView (line);

graph->setFixedHeight (tsize. toInt ());

graph->setFixedWidth (width. toInt ());

graph->move (textX, 0);

graph->setAttribute (Qt:: WA_TranslucentBackground);

graph->setStyleSheet ("border: 0");

graph->show ();

QMap<QGraphicsView*, QVector<float>> temp;

QVector<float> temparr = {};

graph->setProperty ("command", _text. text (). trimmed ());

graph->setProperty ("lineColor", color);

graph->setProperty ("lineSize", linesize);

graph->setProperty ("valuesCount", valuesCount);

graph->setProperty ("fill", fill);

graph->setProperty ("fillColor", fillColor);

graph->setProperty ("gridColor", (gridColor. isEmpty ()?"gray": gridColor));

temp. insert (graph, temparr);

graphs. push_back (temp);

lineWidth += graph->width ();

textX += graph->width ();

}

}

line->setFixedWidth (lineWidth);

line->setFixedHeight (lineHeight);

if (align == "center")

line->move (panel->width () / 2 - lineWidth / 2, lineY);

else if (align == "right") {

line->move (panel->width () - lineWidth - padding. toInt (), lineY);

} else {

line->move (padding. toInt (), lineY);

}

line->show ();

lineY += lineHeight;

panelHeight += lineHeight;

}

}

panel->setFixedHeight (panelHeight + padding. toInt () * 2);

panel->show ();

if (bottom == "" && top == "") panelY += panel->height () + margin. toInt ();

}

}

}

void Monitor:: buttonClicked () {

QPushButton* button = (QPushButton*) sender ();

if (buttons [button]! = "") {

QString command = buttons [button];

auto socket = new QWebSocket ();

socket->open (QUrl ("ws: // " + currentServer->ip + ": 64178"));

connect (socket, &QWebSocket:: connected, [=] () {

QJsonObject obj;

obj. insert ("command", QJsonValue ("execute"));

obj. insert ("password", QJsonValue (currentServer->password));

obj. insert ("execute", QJsonValue (command));

QJsonDocument doc;

doc. setObject (obj);

socket->sendTextMessage (doc. toJson (). replace ("\n", ""));

socket->close ();

});

}

}

void Monitor:: addButtonClicked () {

addServerPanel->setVisible (true);

}

void Monitor:: cancelAdd () {

addServerPanel->setVisible (false);

}

void Monitor:: saveButtonClicked () {

saveAndAdd ();

saveServers ();

}

void Monitor:: saveAndAdd () {

QString name = addServerNameEdit->text (). trimmed ();

QString ip = addServerIpEdit->text (). trimmed ();

QString password = addServerPasswordEdit->text ();

if (name. isEmpty () || ip. isEmpty () || password. isEmpty ()) {

QMessageBox:: information (this, "Ошибка", "Заполните все необходимые поля.", QMessageBox:: Ok);

return;

}

servers. append (Server { ip, password, name });

Panel* panel = new Panel ();

panel->setFixedSize (width (), 160);

panel->setCursor (Qt:: PointingHandCursor);

panel->addStyle ("background: transparent; border: none; border-radius: 0; ");

connect (panel, SIGNAL (clicked ()), this, SLOT (serverClicked ()));

QPixmap serverPixmap (": /images/server");

QLabel* image = new QLabel (panel);

image->setPixmap (serverPixmap. scaled (128, 128));

image->setAttribute (Qt:: WA_TranslucentBackground);

image->move (18, 18);

QLabel* nameLabel = new QLabel (panel);

nameLabel->setText (name);

nameLabel->setStyleSheet ("font-size: 34px; font-weight: bold; color: #2c3e50; ");

nameLabel->setAttribute (Qt:: WA_TranslucentBackground);

nameLabel->adjustSize ();

nameLabel->move (156, 45);

QLabel* ipLabel = new QLabel (panel);

ipLabel->setText (ip);

ipLabel->setStyleSheet ("font-size: 22px; color: #34495e; ");

ipLabel->setAttribute (Qt:: WA_TranslucentBackground);

ipLabel->adjustSize ();

ipLabel->move (156, 84);

mainLayout->addWidget (panel);

addServerPanel->setVisible (false);

addServerNameEdit->clear ();

addServerIpEdit->clear ();

addServerPasswordEdit->clear ();

serverList. insert (panel, servers. last ());

}

void Monitor:: serverClicked () {

loadingLabel = new QLabel (this);

loadingLabel->setGeometry (0, 0, width (), height ());

loadingLabel->setText ("Пожалуйста, подождите. ");

loadingLabel->setStyleSheet ("background: #fff; ");

loadingLabel->setAlignment (Qt:: AlignCenter);

loadingLabel->show ();

Panel* label = (Panel*) sender ();

currentServer = &serverList [label];

auto socket = new QWebSocket ();

socket->open (QUrl ("ws: // " + currentServer->ip + ": 64178"));

connect (socket, SIGNAL (connected ()), this, SLOT (socketSuccess ()));

connect (socket, SIGNAL (error (QAbstractSocket:: SocketError)), this, SLOT (socketError ()));

}

void Monitor:: socketSuccess () {

loadingLabel->deleteLater ();

getBackground ();

auto socket = (QWebSocket*) sender ();

QJsonObject obj;

obj. insert ("command", QJsonValue ("get-template"));

obj. insert ("password", QJsonValue (currentServer->password));

QJsonDocument doc;

doc. setObject (obj);

socket->sendTextMessage (doc. toJson (). replace ("\n", ""));

connect (socket, SIGNAL (textMessageReceived (QString)), this, SLOT (serverAnswered (QString)));

connect (socket, SIGNAL (binaryMessageReceived (QByteArray)), this, SLOT (templateCame (QByteArray)));

}

void Monitor:: socketError () {

loadingLabel->hide ();

if (updateTimer)

updateTimer->stop ();

for (QObject* child: templateParent->children ()) {

( (QWidget*) child) - >hide ();

}

templateParent->deleteLater ();

templateParent = new QWidget (this);

if (connected)

paintControls ();

( (QWebSocket*) sender ()) - >close ();

QMessageBox:: critical (this, "Ошибка", "Нет соединения с сервером.", QMessageBox:: Ok);

connected = false;

}

void Monitor:: templateCame (QByteArray templateData) {

addButton->setVisible (false);

cWidget->setVisible (false);

loadTemplate (templateData);

templateLoaded = true;

startUpdateTimer ();

connected = true;

if (backgroundLoaded)

applyBackground ();

}

void Monitor:: startUpdateTimer () {

updateTimer->singleShot (2500, this, SLOT (updateInfo ()));

}

void Monitor:: updateInfo () {

mainSocket = new QWebSocket ();

mainSocket->open (QUrl ("ws: // " + currentServer->ip + ": 64178"));

connect (mainSocket, SIGNAL (connected ()), this, SLOT (updateStart ()));

connect (mainSocket, SIGNAL (textMessageReceived (QString)), this, SLOT (updateCame (QString)));

updateTimer->singleShot (2500, this, SLOT (updateInfo ()));

}

void Monitor:: updateStart () {

auto socket = (QWebSocket*) sender ();

QJsonObject obj;

obj. insert ("command", QJsonValue ("update"));

obj. insert ("password", QJsonValue (currentServer->password));

obj. insert ("count", QJsonValue (values. count () + graphs. count ()));

int fi = 0;

for (fi = 0; fi < values. count (); fi++) {

QString command = values. values (). at (fi). values (). at (0);

obj. insert ("execute" + QString:: number (fi), QJsonValue (command));

}

for (int i = 0; i < graphs. count (); i++) {

QString command = graphs. at (i). keys (). at (0) - >property ("command"). toString ();

obj. insert ("execute" + QString:: number (i + fi), QJsonValue (command));

}

QJsonDocument doc;

doc. setObject (obj);

socket->sendTextMessage (doc. toJson (). replace ("\n", ""));

}

void Monitor:: updateCame (QString message) {

QJsonObject doc = QJsonDocument:: fromJson (message. toUtf8 ()). object ();

QDateTime now = QDateTime:: currentDateTime ();

QFile logFile (logDir + logFileName);

logFile. open (QIODevice:: WriteOnly | QIODevice:: Append);

logFile. write (QString (" [=== " + now. toString (Qt:: SystemLocaleLongDate) + " ===] \n"). toStdString (). c_str ());

QString logString = "";

if (doc ["success"]. toBool () == true) {

int count = doc ["count"]. toInt ();

for (int i = 0; i < count; i++) {

QString value = doc ["execute" + QString:: number (i)]. toString (). trimmed ();

if (values. count () >= (i + 1)) {

QLabel* label = values. values (). at (i). keys (). at (0);

label->setText (value);

auto line = (QLabel*) label->parentWidget ();

auto children = line->children ();

int x = 0;

for (QObject* _child: children) {\

auto child = (QLabel*) _child;

child->adjustSize ();

child->move (x, child->geometry (). y ());

x += child->width ();

}

line->setFixedWidth (x);

if (! label->property ("log"). toString (). isEmpty ()) {

logString += label->property ("log"). toString () + " " + value + "\n";

}

auto _parent = (Panel*) line->parentWidget ();

auto _aligment = ( (Panel*) line->parentWidget ()) - >alignment ();

if (_aligment == Qt:: AlignCenter)

line->move (_parent->width () / 2 - line->width () / 2, line->geometry (). y ());

else if (_aligment == Qt:: AlignRight) {

line->move (_parent->width () - line->width () - _parent->property ("padding"). toString (). toInt (), line->geometry (). y ());

} else {

line->move (_parent->property ("padding"). toString (). toInt (), line->geometry (). y ());

}

} else {

QGraphicsView* graphParent = graphs. at (i - values. count ()). keys (). at (0);

QVector<float>* graphValues = &graphs [i - values. count ()] [graphParent];

int graphHeight = graphParent->height ();

int graphWidth = graphParent->width ();

int valuesCount = graphParent->property ("valuesCount"). toString (). toInt ();

graphValues->push_back (value. toFloat ());

if (graphValues->count () > valuesCount) {

graphValues->removeFirst ();

}

float maxValue = 0, minValue = 0;

maxValue = minValue = graphValues->at (0);

for (float value: *graphValues) {

if (maxValue < value)

maxValue = value;

if (minValue > value)

minValue = value;

}

float highestPoint = maxValue / 0.9;

float lowestPoint = minValue * 0.9;

QGraphicsScene* scene = new QGraphicsScene (graphParent);

scene->setSceneRect (0, 0, graphWidth - 2, graphHeight - 2); \

QPen pen;

pen. setColor (QColor (graphParent->property ("lineColor"). toString ()));

pen. setWidth (graphParent->property ("lineSize"). toInt ());

QPolygonF poly;

poly. append (QPointF (0, graphHeight));

graphParent->setRenderHint (QPainter:: Antialiasing, true);

graphParent->setRenderHint (QPainter:: SmoothPixmapTransform, true);

graphParent->setRenderHint (QPainter:: HighQualityAntialiasing, true);

float minY = graphHeight * 0.1, height = graphHeight;

int gX = 0, gY = minY + ( (graphValues->at (0) - lowestPoint) * 100/ (highestPoint - lowestPoint)) * graphHeight / 100;

for (int i = 0; i < graphValues->count (); i++) {

float current = graphValues->at (i);

float tempX = graphWidth / (valuesCount - 2) * i;

float tempY = minY + ( (current - lowestPoint) * 100/ (highestPoint - lowestPoint)) * graphHeight * 0.9/100;

if (graphValues->count () == valuesCount) {

poly. append (QPointF (tempX, height - tempY));

}

scene->addLine (gX, height - gY, tempX, height - tempY, pen);

gX = tempX;

gY = tempY;

}

if (graphValues->count () >= (valuesCount - 1) && ! graphParent->property ("fill"). toString (). isEmpty ()) {

QGraphicsPolygonItem* item = new QGraphicsPolygonItem ();

QString fillColor = graphParent->property ("fillColor"). toString ();

poly. append (QPointF (graphWidth, graphHeight));

item->setPolygon (poly);

item->setPen (QPen (QColor (0, 0, 0, 0)));

item->setBrush (QBrush (QColor (fillColor. isEmpty ()?"green": fillColor)));

scene->addItem (item);

}

QColor gridColor (graphParent->property ("gridColor"). toString ());

gridColor. setAlpha (0.7);

QPen gridPen;

pen. setColor (gridColor);

gridPen. setWidthF (0.14);

for (int i = 0; i < valuesCount; i++) {

float gridX = graphWidth / (valuesCount - 2) * i;

scene->addLine (gridX, 0, gridX, graphHeight, gridPen);

}

for (int i = 1; i < 11; i++)

scene->addLine (0, graphHeight * i / 10, graphWidth, graphHeight * i / 10, gridPen);

QString maxValueToShow = QString:: number (roundDouble (maxValue,

2));

QString minValueToShow = QString:: number (roundDouble (minValue,

2));

QFont textFont;

textFont. setPixelSize (graphHeight * 0.18);

// top value

QPolygonF topValue;

topValue. append (QPointF (graphWidth - graphHeight * 0.1, graphHeight * 0.1));

topValue. append (QPointF (graphWidth - graphHeight * 0.1, graphHeight * 0.3));

topValue. append (QPointF (graphWidth * 0.85 - graphHeight * 0.1, graphHeight * 0.3));

topValue. append (QPointF (graphWidth * 0.85 - graphHeight * 0.1, graphHeight * 0.1));

QGraphicsPolygonItem* topValueItem = new QGraphicsPolygonItem ();

topValueItem->setPolygon (topValue);

topValueItem->setPen (gridPen);

topValueItem->setBrush (QBrush (QColor ("black")));

scene->addItem (topValueItem);

QGraphicsTextItem* topValueText = new QGraphicsTextItem (maxValueToShow);

topValueText->setFont (textFont);

topValueText->setDefaultTextColor (QColor ("white"));

topValueText->adjustSize ();

QRectF topRegion = topValueText->boundingRect ();

float topRegionWidth = topRegion. width ();

float topRegionHeight = topRegion. height ();

topValueText->setPos (graphWidth * 0.85 - graphHeight * 0.1 + graphWidth * 0.15/2 - topRegionWidth / 2, graphHeight * 0.1 + graphHeight * 0.2/2 - topRegionHeight / 2);

scene->addItem (topValueText);

// bottom value

QPolygonF bottomValue;

bottomValue. append (QPointF (graphWidth - graphHeight * 0.1, graphHeight * 0.9));

bottomValue. append (QPointF (graphWidth - graphHeight * 0.1, graphHeight * 0.7));

bottomValue. append (QPointF (graphWidth * 0.85 - graphHeight * 0.1, graphHeight * 0.7));

bottomValue. append (QPointF (graphWidth * 0.85 - graphHeight * 0.1, graphHeight * 0.9));

QGraphicsPolygonItem* bottomValueItem = new QGraphicsPolygonItem ();

bottomValueItem->setPolygon (bottomValue);

bottomValueItem->setPen (gridPen);

bottomValueItem->setBrush (QBrush (QColor ("black")));

scene->addItem (bottomValueItem);

QGraphicsTextItem* bottomValueText = new QGraphicsTextItem (minValueToShow);

bottomValueText->setFont (textFont);

bottomValueText->setDefaultTextColor (QColor ("white"));

bottomValueText->adjustSize ();

QRectF bottomRegion = bottomValueText->boundingRect ();

float bottomRegionWidth = bottomRegion. width ();

float bottomRegionHeight = bottomRegion. height ();

bottomValueText->setPos (graphWidth * 0.85 - graphHeight * 0.1 + graphWidth * 0.15/2 - bottomRegionWidth / 2, graphHeight * 0.7 + graphHeight * 0.2/2 - bottomRegionHeight / 2);

scene->addItem (bottomValueText);

graphParent->setScene (scene);

}

}

}

logFile. write (QString (logString + "\n\n"). toStdString (). c_str ());

logFile. close ();

( (QWebSocket*) sender ()) - >close ();

}

void Monitor:: getBackground () {

auto socket = new QWebSocket ();

socket->open (QUrl ("ws: // " + currentServer->ip + ": 64178"));

connect (socket, &QWebSocket:: connected, [=] () {

QJsonObject obj;

obj. insert ("command", QJsonValue ("get-background"));

obj. insert ("password", QJsonValue (currentServer->password));

QJsonDocument doc;

doc. setObject (obj);

socket->sendTextMessage (doc. toJson ());

});

connect (socket, SIGNAL (binaryMessageReceived (QByteArray)), this, SLOT (gotBackground (QByteArray)));

}

void Monitor:: gotBackground (QByteArray data) {

backgroundLoaded = true;

bg = true;

background = data;

( (QWebSocket*) sender ()) - >close ();

if (templateLoaded)

applyBackground ();

}

void Monitor:: gotBackgroundError (QString data) {

bg = false;

Q_UNUSED (data);

}

void Monitor:: serverAnswered (QString message) {

QJsonObject doc = QJsonDocument:: fromJson (message. toUtf8 ()). object ();

if (doc ["success"]. toBool () == false) {

QMessageBox:: critical (this, "Ошибка", "Ошибка подключения: проверьте пароль.", QMessageBox:: Ok);

}

( (QWebSocket*) sender ()) - >close ();

}

void Monitor:: selectClicked (int index) {

QComboBox* select = (QComboBox*) sender ();

QString command = commands. value (select). value (index);

auto socket = new QWebSocket ();

socket->open (QUrl ("ws: // " + currentServer->ip + ": 64178"));

connect (socket, &QWebSocket:: connected, [=] () {

QJsonObject obj;

obj. insert ("command", QJsonValue ("execute"));

obj. insert ("password", QJsonValue (currentServer->password));

obj. insert ("execute", QJsonValue (command));

QJsonDocument doc;

doc. setObject (obj);

socket->sendTextMessage (doc. toJson (). replace ("\n", ""));

socket->close ();

});

select->setCurrentIndex (-1);

select->clearFocus ();

}

void Monitor:: applyBackground () {

QLabel* backgroundLabel = new QLabel (templateParent);

backgroundLabel->setGeometry (0, 0, width (), height ());

QPixmap px;

px. loadFromData (background, "jpg");

backgroundLabel->setPixmap (px. scaled (width (), height ()));

backgroundLabel->lower ();

backgroundLabel->show ();

}

bool Monitor:: eventFilter (QObject *sender, QEvent *event) {

if (event->type () == QEvent:: ActivationChange) {

if (firstLoad) {

paintControls ();

firstLoad = false;

}

}

return QMainWindow:: eventFilter (sender, event);

}

void Monitor:: keyReleaseEvent (QKeyEvent *event) {

if ( ( (QKeyEvent*) event) - >key () == Qt:: Key_Back) {

if (! connected) {

qApp->quit ();

return;

}

if (updateTimer)

updateTimer->stop ();

for (QObject* child: templateParent->children ()) {

( (QWidget*) child) - >hide ();

}

templateParent->deleteLater ();

templateParent = new QWidget (this);

paintControls ();

mainSocket->close ();

connected = false;

event->accept ();

return;

}

}

Monitor:: ~Monitor () {

}

// файл clickablelabel. h

#ifndef CLICKABLELABEL

#define CLICKABLELABEL

#include <QLabel>

#include <QMouseEvent>

class ClickableLabel: public QLabel {

Q_OBJECT

public:

ClickableLabel (QWidget* parent = 0);

~ClickableLabel () {}

signals:

void clicked ();

protected:

void mousePressEvent (QMouseEvent * event);

};

#endif // CLICKABLELABEL

// файл clickablelabel. cpp

#include "clickablelabel. h"

ClickableLabel:: ClickableLabel (QWidget* parent): QLabel (parent) {

}

void ClickableLabel:: mousePressEvent (QMouseEvent* /*event*/) {

emit clicked ();

}

// файл myserver. h

#ifndef MYSERVER

#define MYSERVER

#include <QtCore>

#include <QtNetwork>

#include <QtWebSockets>

#include <QJsonDocument>

class MyServer: public QObject {

Q_OBJECT

public:

explicit MyServer (int port, QString password, QByteArray templateData, QByteArray bg = "") {

server = new QWebSocketServer ("TDM Server", QWebSocketServer:: NonSecureMode, this);

server->listen (QHostAddress:: Any, port);

this->templateData = templateData;

this->password = password;

if (bg! = "") {

this->bg = true;

this->background = bg;

}

connect (server, SIGNAL (newConnection ()), this, SLOT (clientConnected ()));

}

~MyServer () {}

private:

QWebSocketServer* server;

QByteArray templateData;

QByteArray background;

QString password;

private slots:

void clientConnected () {

QWebSocket* clientSocket = server->nextPendingConnection ();

connect (clientSocket, SIGNAL (textMessageReceived (QString)), this, SLOT (slotReadClient (QString)));

}

void slotReadClient (QString message) {

QWebSocket* clientSocket = (QWebSocket*) sender ();

QJsonDocument doc = QJsonDocument:: fromJson (message. toUtf8 ());

auto command = doc. object () ["command"]. toString ();

auto pass = doc. object () ["password"]. toString ();

if (pass! = password) {

clientSocket->sendTextMessage ("{success: false,error: \"Wrong password\"}");

return;

}

if (command == "get-background" && bg) {

clientSocket->sendBinaryMessage (background);

} else if (command == "get-background" &&! bg) {

clientSocket->sendTextMessage ("{success: false,error: \"No background. \"}");

}

if (command == "get-template") {

clientSocket->sendBinaryMessage (templateData);

}

if (command == "update") {

auto count = doc. object () ["count"]. toInt ();

QString answer;

QJsonDocument json;

QJsonObject obj;

obj ["success"] = QJsonValue (true);

obj ["count"] = QJsonValue (count);

for (int i = 0; i < count; i++) {

auto execute = doc. object () ["execute" + QString:: number (i)]. toString ();

QProcess* process = new QProcess ();

process->start ("/bin/bash", QStringList () << "-c" <<

"echo $ (" + execute + ")");

process->waitForFinished (1000);

auto value = process->readAll (). trimmed ();

obj ["execute" + QString:: number (i)] = QJsonValue (value. toStdString (). c_str ());

}

json. setObject (obj);

answer = json. toJson ();

clientSocket->sendTextMessage (answer);

}

if (command == "execute") {

auto execute = doc. object () ["execute"]. toString ();

QProcess* process = new QProcess ();

process->start ("/bin/bash", QStringList () << "-c" << execute);

}

}

};

#endif // MYSERVER

// файл panel. h

#ifndef PANEL_H

#define PANEL_H

#include <QMainWindow>

#include <QLabel>

#include <clickablelabel. h>

class Panel: public ClickableLabel {

Q_OBJECT

public:

Panel (QWidget *parent = 0);

void addStyle (QString style);

void setHoverBackground (QString bg);

~Panel ();

private:

QString style;

};

#endif // PANEL_H

// файл panel. cpp

#include <QtCore>

#include <QtWidgets>

#include "panel. h"

Panel:: Panel (QWidget *parent): ClickableLabel (parent) {

style = "Panel { border: 1px solid #444; background: #777; border-radius: 25px; }";

setStyleSheet (style);

}

void Panel:: addStyle (QString style) {

this->style = this->style. mid (0, this->style. length () - 1);

this->style += style + " }";

setStyleSheet (this->style);

}

Panel:: ~Panel () {

}

// файл TDM. pro

QT += core gui xml websockets

greaterThan (QT_MAJOR_VERSION,

4): QT += widgets

TARGET = TDM

TEMPLATE = app

SOURCES += main. cpp\

monitor. cpp \

panel. cpp \

clickablelabel. cpp

HEADERS += monitor. h \

panel. h \

other. h \

clickablelabel. h \

myserver. h

DISTFILES += default. tpl

CONFIG += C++11

RESOURCES += resources. qrc

LIBS += - L/usr/lib/i386-linux-gnu/mesa

В даному експлуатаційному документі наведено керівництво оператора щодо застосування та експлуатації додатку "кросплатформовий клієнт-серверний додаток для віддаленого моніторингу та управління персональним комп'ютером - TDM".

У даному програмному документі, в розділі "Призначення програми" вказані відомості про призначення програми та інформація, достатня для розуміння функцій додатку та його експлуатації.

В розділі "Умови виконання програми" зазначено умови, необхідні для роботи додатку (мінімальний склад апаратних і програмних засобів тощо).

В даному програмному документі, в розділі "Виконання програми" вказана послідовність дій оператора, що забезпечують завантаження, запуск, виконання і завершення програми, наведений опис функцій, формату і можливих варіантів команд, за допомогою яких оператор здійснює завантаження і управляє виконанням програми, а також відповіді програми на ці команди.

У розділі "Повідомлення оператору" наведено тексти повідомлень, що видаються в ході виконання програми, опис їх змісту та відповідні дії оператора.

1 ПРИЗНАЧЕННЯ ПРОГРАМИ

Додаток під назвою "кросплатформовий клієнт-серверний додаток для віддаленого моніторингу та управління персональним комп'ютером - TDM" призначений для віддаленого нагляду за комп'ютером без наявності фізичного доступу, для управління та виправлення помилок, що можуть виникати на комп'ютері, а також для ведення статистики деяких даних.

2 УМОВИ ВИКОНАННЯ ПРОГРАМИ

Програма складається з клієнтської та серверної частин, кожна з яких має свои вимоги до програмної та апаратної частини.

Мінімальна конфігурація для клієнтської частини:

комп'ютер або смартфон з операційною системою Android 3.2 (або быльше) чи Windows XP (або більше);

процесор з тактовою частотою 1 ГГц;

512 Мб оперативної пам'яті;

монітор або дісплей з розрішенням 854х480.

Мінімальна конфігурація для серверної частини:

комп'ютер з операційною системою на базі GNU/Linux;

процесор з тактовою частотою 0.6 ГГц;

128 Мб оперативної пам'яті.

3 ВИКОНАННЯ ПРОГРАМИ

Робота з серверною частиною програми починається з її запуском через термінал. Для того, чтоб запустити додаток у режимі серверу, треба вказати аргумент “-s”. Також оператор повинен вказати такі аргументи, як: пароль для входу (“-p”), файл шаблону (“-t”), файл-картинка з фоном (“-b”). Після цього сервер запускається та починає приймати з'єднання клієнтів.

Рисунок 3.1 - Запуск серверу

Робота з клієнтською частиною програми починається з того, що робітник повинен запустити додаток. Перше, що він побачить на екрані - список серверів, якщо вони вже були додані, та кнопку з піктограмую “Додати”. При натисканні на кнопку відкривається спеціальна форма для додавання серверу, де оператор повинен заповнити три поля: IP-адрес серверу, пароль для підключення та назва серверу. Під полями на формі знаходяться дві кнопки з піктограмами “Зберегти" та “Закрити”, зправа наліво.

Рисунок 3.2 - Головний екран клієнтської частини

При натисканні на один з серверів, додаток спробує підключитись до нього. Якщо йому це вдасться, оператор побачить шаблон у зрозумілій для людини формі, тобто фон та елементи керування. Дальніше використання програми залежить тільки вид шаблону, що був вказаний на сервері.

Рисунок 3.3 - Адаптований шаблон

4 ПОВІДОМЛЕННЯ ОПЕРАТОРУ

Якщо користувач робить некоректні дії, то в програмі будуть виводитися підказки та попередження. Наприклад, при додаванні інформації, якщо будут введені некоректні дані - йому буде виедена на єкран відповідна підказка.

Рисунок 4.1 - Помилка при невірному паролі

Рисунок 4.2 - Підключення до серверу, що не відповідає

Рисунок 4.3 - У шаблоні не вказана товщина лінії для графіку

Перелік посилань

1. Задушко П.І. Основи Qt: створення мультиплатформового додатку. - К.: НМК ВО, 2013. - 176 с.

2. ГОСТ 7.1-84. Библиографическое описание документа. Общие требования и правила составления.

3. Ільдар Хабибулин. Самовчитель з XML. - К.: Наук. Думка, 2011. - 542 с.

4. Елементи інформатики: довідник, В.С. Височанський, А.І. Кардаш, В.С. Костєв, В.В. Черняхівський. - К.: Наук. Думка, 2012. - 224 с.

5. Задрозький А.В. Технологія кліент-сервер. - Л.: Книга, 2014. - 164 с.

6. Околевич В.В. Qt 5 на прикладах. - К.: Новий дім, 2009. - 311 с.

7. Шеховцов В.А. Операційні системи. - Л.: Теза, 2011. - 221 с.

8. Литвиненко Н.А. Технология программирования на С++. К.: Наук. Думка, 2013. - 401 с.

9. Азов В.І. С++: кросплатформова розробка. - Д.: Пристань, 2012. - 144 с.

10. Рамбо Д.І. UML 2.0. Объектно-ориентированное моделирование и разработка. - П.: Пітер, 2008. - 287 с.

11. Васильчук М.В. та ін. Основи охорони праці. - К.: Просвіта, 2009. - 208 с.

12. Бойчик I.М. Економіка підприємства. - К.: Атіка, 2004. - 480 с.

Размещено на Allbest.ru


Подобные документы

  • Характеристика програмної взаємодії людини з комп'ютером. Визначення функціональних та експлуатаційних потреб при голосовому управлінні. Реалізація програмного забезпечення. Розробка тестів та тестування системи. Аналіз ефективності даної програми.

    курсовая работа [2,8 M], добавлен 15.10.2014

  • Аналіз технологій розробки систем моніторингу і управління та різноманітності мов програмування. Створення проекту структури Інтернет-магазину, розробка бази даних, UML-діаграми та алгоритму виконання функцій додатку. Результати тестування програми.

    дипломная работа [1,6 M], добавлен 08.06.2015

  • Програмний засіб моніторингу реалізації проектів з побудовою графіків та завданням відхилень. Вибір моделі життєвого циклу розробки додатків Rapid Application Development об'єктно-орієнтованою мовою програмування C# на платформі Microsoft .NET Framework.

    дипломная работа [1,4 M], добавлен 11.09.2012

  • Аналіз функціонування файлового менеджера WINDOWS COMMANDER. Ключові якості програми: операцї з файлами, управління архівами, локальні меню, вбудований FTP-клієнт. З'днання з іншим комп'ютером. Контрольні суми. Функції різних версій WINDOWS COMMANDER.

    дипломная работа [48,2 K], добавлен 14.12.2007

  • Розробка програмної утиліти для моніторингу та контролю енергоспоживання портативних комп’ютерів. Аналіз особливостей та дослідження найбільших витрат енергоспоживання в ноутбуках. Виявлення помилок зміни яскравості екрану. Опис інтерфейсу, тестування.

    курсовая работа [3,9 M], добавлен 19.11.2014

  • Класифікація та характеристики інфрачервоних систем. Принцип роботи фотодіода. Встановлення норм часу по розробці дистанційного управління медіасистемою ПК. Основні можливості програми Light Alloy. Вимоги техніки безпеки при роботі з електроприладами.

    дипломная работа [1,0 M], добавлен 19.08.2012

  • Аналіз систем розумного будинку та його параметрів. Принципи автоматизації системи освітленості в приміщені. Вибір та аналіз компонентів інтелектуальної системи управління розумного будинку. Функції систем моніторингу освітленості розумного будинку.

    дипломная работа [2,0 M], добавлен 19.01.2021

  • Набір програм, призначених для управління комп'ютером, зберігання і обробки інформації, для організації роботи всіх підключених до комп'ютера пристроїв. Загальні відомості про операційну систему. Історичний аспект розвитку ОС Windows та його можливості.

    реферат [2,3 M], добавлен 30.03.2009

  • Загальна класифікація роботів. Проектування та розробка системи управління промисловим роботом "Електроніка НЦ ТМ-01" на базі IBM–сумісного персонального комп’ютера. Структурно функціональна схема взаємодії систем робота. Блок схема системи управління.

    дипломная работа [3,6 M], добавлен 25.10.2012

  • Мережне адміністрування. Програми для віддаленого адміністрування. Віддалене управління засобами Telnet. Можливості програми Remote Administrator 2.2. Безпека Radmin. Режим обміну файлами. Запит логіна і пароля перед початком роботи з File Manager.

    курсовая работа [1,5 M], добавлен 24.03.2009

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.