Кросплатформовий клієнт-серверний додаток для віддаленого моніторингу та управління персональним комп’ютером — 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Набір програм, призначених для управління комп'ютером, зберігання і обробки інформації, для організації роботи всіх підключених до комп'ютера пристроїв. Загальні відомості про операційну систему. Історичний аспект розвитку ОС Windows та його можливості.
реферат [2,3 M], добавлен 30.03.2009Аналіз систем розумного будинку та його параметрів. Принципи автоматизації системи освітленості в приміщені. Вибір та аналіз компонентів інтелектуальної системи управління розумного будинку. Функції систем моніторингу освітленості розумного будинку.
дипломная работа [2,0 M], добавлен 19.01.2021Загальна класифікація роботів. Проектування та розробка системи управління промисловим роботом "Електроніка НЦ ТМ-01" на базі IBM–сумісного персонального комп’ютера. Структурно функціональна схема взаємодії систем робота. Блок схема системи управління.
дипломная работа [3,6 M], добавлен 25.10.2012Мережне адміністрування. Програми для віддаленого адміністрування. Віддалене управління засобами Telnet. Можливості програми Remote Administrator 2.2. Безпека Radmin. Режим обміну файлами. Запит логіна і пароля перед початком роботи з File Manager.
курсовая работа [1,5 M], добавлен 24.03.2009