/
seneka.y
/
ClientServer
Обзор
Документация
Войти
/
seneka.y
/
ClientServer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
client/mainwindow.cpp
373 строки
12 KB
Julia Sinika
Initial commit
09 ноя 2025, 22:05
09 ноя 2025, 22:05
bfef146
Код
Авторство
О чём код?
#include "mainwindow.h" #include <QFormLayout> #include <QHeaderView> #include <QMessageBox> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QDebug> #include <QTimer> #include <QStatusBar> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_serverHost("127.0.0.1") , m_serverPort(12345) , m_selectedUserId(-1) , m_reconnectAttempts(0) { setupUI(); m_socket = new QTcpSocket(this); connect(m_socket, &QTcpSocket::connected, this, &MainWindow::onConnected); connect(m_socket, &QTcpSocket::disconnected, this, &MainWindow::onDisconnected); connect(m_socket, &QTcpSocket::readyRead, this, &MainWindow::onReadyRead); connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::errorOccurred), this, &MainWindow::onSocketError); connectToServer(); } MainWindow::~MainWindow() { if (m_socket && m_socket->state() == QAbstractSocket::ConnectedState) { m_socket->disconnectFromHost(); } } void MainWindow::setupUI() { setWindowTitle("User Manager"); resize(700, 500); QWidget* centralWidget = new QWidget(this); setCentralWidget(centralWidget); QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget); QFormLayout* formLayout = new QFormLayout(); m_usernameEdit = new QLineEdit(); m_usernameEdit->setPlaceholderText("Введите имя пользователя"); formLayout->addRow("Username:", m_usernameEdit); m_emailEdit = new QLineEdit(); m_emailEdit->setPlaceholderText("Введите email"); formLayout->addRow("Email:", m_emailEdit); mainLayout->addLayout(formLayout); QHBoxLayout* buttonLayout = new QHBoxLayout(); m_addButton = new QPushButton("Добавить"); m_updateButton = new QPushButton("Обновить выбранного"); m_deleteButton = new QPushButton("Удалить выбранного"); m_refreshButton = new QPushButton("Обновить список"); m_updateButton->setEnabled(false); m_deleteButton->setEnabled(false); m_addButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_updateButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_deleteButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_refreshButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); buttonLayout->addWidget(m_addButton); buttonLayout->addWidget(m_updateButton); buttonLayout->addWidget(m_deleteButton); buttonLayout->addWidget(m_refreshButton); mainLayout->addLayout(buttonLayout); m_userTable = new QTableWidget(); m_userTable->setColumnCount(3); m_userTable->setHorizontalHeaderLabels({"ID", "Username", "Email"}); m_userTable->horizontalHeader()->setStretchLastSection(true); m_userTable->setEditTriggers(QAbstractItemView::NoEditTriggers); m_userTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_userTable->setSelectionMode(QAbstractItemView::SingleSelection); mainLayout->addWidget(m_userTable); m_statusLabel = new QLabel("Отключено"); m_statusLabel->setStyleSheet("QLabel { color: red; font-weight: bold; }"); mainLayout->addWidget(m_statusLabel); connect(m_addButton, &QPushButton::clicked, this, &MainWindow::onAddUserClicked); connect(m_updateButton, &QPushButton::clicked, this, &MainWindow::onUpdateUserClicked); connect(m_deleteButton, &QPushButton::clicked, this, &MainWindow::onDeleteUserClicked); connect(m_refreshButton, &QPushButton::clicked, this, &MainWindow::onRefreshClicked); connect(m_userTable, &QTableWidget::itemSelectionChanged, this, &MainWindow::onTableSelectionChanged); } void MainWindow::connectToServer() { if (m_socket->state() == QAbstractSocket::ConnectedState) { return; } showMessage("Подключение к серверу..."); m_socket->connectToHost(m_serverHost, m_serverPort); bool connected = m_socket->waitForConnected(3000); if (!connected) { qWarning() << "Failed to connect to server" << m_socket->errorString(); } } void MainWindow::ensureConnected() { if (m_socket->state() != QAbstractSocket::ConnectedState) { qWarning() << "Connection lost:" << m_socket->errorString(); if (m_reconnectAttempts < 3) { m_reconnectAttempts++; showMessage("Соединение потеряно, переподключаемся..."); connectToServer(); } else { QMessageBox::warning(this, "Ошибка", "Не удалось переподключиться к серверу!"); m_reconnectAttempts = 0; } } else { m_reconnectAttempts = 0; } } void MainWindow::onConnected() { qInfo() << "Connected to server" << m_socket->peerAddress().toString(); showMessage("Подключено к серверу"); m_statusLabel->setText("Подключено"); m_statusLabel->setStyleSheet("QLabel { color: green; font-weight: bold; }"); m_reconnectAttempts = 0; onRefreshClicked(); } void MainWindow::onDisconnected() { qWarning() << "Disconnected from server"; showMessage("Отключено от сервера", true); m_statusLabel->setText("Отключено"); m_statusLabel->setStyleSheet("QLabel { color: red; font-weight: bold; }"); m_receiveBuffer.clear(); } void MainWindow::onSocketError(QAbstractSocket::SocketError error) { qCritical() << "Socket error:" << error << m_socket->errorString(); QString errorMsg; switch(error) { case QAbstractSocket::ConnectionRefusedError: errorMsg = "Сервер отклонил соединение"; break; case QAbstractSocket::HostNotFoundError: errorMsg = "Хост не найден"; break; case QAbstractSocket::SocketTimeoutError: errorMsg = "Таймаут подключения"; break; case QAbstractSocket::NetworkError: errorMsg = "Сеть недоступна"; break; default: errorMsg = "Ошибка сокета"; } showMessage("Ошибка: " + errorMsg, true); } void MainWindow::onAddUserClicked() { ensureConnected(); QString username = m_usernameEdit->text().trimmed(); QString email = m_emailEdit->text().trimmed(); if (username.isEmpty() || email.isEmpty()) { QMessageBox::warning(this, "Ошибка", "Заполните все поля!"); return; } if (m_socket->state() != QAbstractSocket::ConnectedState) { QMessageBox::warning(this, "Ошибка", "Нет подключения к серверу!"); return; } QJsonObject request; request["action"] = "add_user"; request["username"] = username; request["email"] = email; sendRequest(request); } void MainWindow::onUpdateUserClicked() { ensureConnected(); if (m_selectedUserId < 0) { QMessageBox::warning(this, "Ошибка", "Выберите пользователя из таблицы!"); return; } QString username = m_usernameEdit->text().trimmed(); QString email = m_emailEdit->text().trimmed(); if (username.isEmpty() || email.isEmpty()) { QMessageBox::warning(this, "Ошибка", "Заполните все поля!"); return; } if (m_socket->state() != QAbstractSocket::ConnectedState) { QMessageBox::warning(this, "Ошибка", "Нет подключения к серверу!"); return; } QJsonObject request; request["action"] = "update_user"; request["id"] = m_selectedUserId; request["username"] = username; request["email"] = email; sendRequest(request); } void MainWindow::onDeleteUserClicked() { ensureConnected(); if (m_selectedUserId < 0) { QMessageBox::warning(this, "Ошибка", "Выберите пользователя из таблицы!"); return; } QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "Подтверждение", "Вы уверены, что хотите удалить выбранного пользователя?", QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::No) { return; } if (m_socket->state() != QAbstractSocket::ConnectedState) { QMessageBox::warning(this, "Ошибка", "Нет подключения к серверу!"); return; } QJsonObject request; request["action"] = "delete_user"; request["id"] = m_selectedUserId; sendRequest(request); } void MainWindow::onTableSelectionChanged() { QList<QTableWidgetItem*> selectedItems = m_userTable->selectedItems(); if (selectedItems.isEmpty()) { m_selectedUserId = -1; m_updateButton->setEnabled(false); m_deleteButton->setEnabled(false); clearInputFields(); return; } int row = selectedItems.first()->row(); m_selectedUserId = m_userTable->item(row, 0)->text().toInt(); m_usernameEdit->setText(m_userTable->item(row, 1)->text()); m_emailEdit->setText(m_userTable->item(row, 2)->text()); m_updateButton->setEnabled(true); m_deleteButton->setEnabled(true); } void MainWindow::onRefreshClicked() { ensureConnected(); if (m_socket->state() != QAbstractSocket::ConnectedState) { QMessageBox::warning(this, "Ошибка", "Нет подключения к серверу!"); return; } QJsonObject request; request["action"] = "get_users"; sendRequest(request); } void MainWindow::sendRequest(const QJsonObject& request) { QJsonDocument doc(request); QByteArray data = doc.toJson(QJsonDocument::Compact); qint64 written = m_socket->write(data); if (written == -1) { qCritical() << "Failed to send request:" << m_socket->errorString(); } else { m_socket->flush(); } } void MainWindow::onReadyRead() { QByteArray newData = m_socket->readAll(); m_receiveBuffer.append(newData); QJsonParseError parseError; QJsonDocument doc = QJsonDocument::fromJson(m_receiveBuffer, &parseError); if (parseError.error == QJsonParseError::NoError) { processResponse(m_receiveBuffer); m_receiveBuffer.clear(); } } void MainWindow::processResponse(const QByteArray& data) { QJsonParseError parseError; QJsonDocument doc = QJsonDocument::fromJson(data, &parseError); if (parseError.error != QJsonParseError::NoError) { qWarning() << "JSON parse error:" << parseError.errorString(); return; } QJsonObject response = doc.object(); QString status = response["status"].toString(); if (status == "success") { if (response.contains("users")) { QJsonArray users = response["users"].toArray(); updateUserTable(users); showMessage("Список обновлен"); } else { showMessage(response["message"].toString()); clearInputFields(); QTimer::singleShot(100, this, &MainWindow::onRefreshClicked); } } else { showMessage("Ошибка: " + response["message"].toString(), true); } } void MainWindow::updateUserTable(const QJsonArray& users) { m_userTable->setRowCount(0); for (int i = 0; i < users.size(); ++i) { QJsonObject user = users[i].toObject(); int row = m_userTable->rowCount(); m_userTable->insertRow(row); m_userTable->setItem(row, 0, new QTableWidgetItem(QString::number(user["id"].toInt()))); m_userTable->setItem(row, 1, new QTableWidgetItem(user["username"].toString())); m_userTable->setItem(row, 2, new QTableWidgetItem(user["email"].toString())); } } void MainWindow::showMessage(const QString& message, bool isError) { if (isError) { QMessageBox::warning(this, "Ошибка", message); } statusBar()->showMessage(message, 3000); } void MainWindow::clearInputFields() { m_usernameEdit->clear(); m_emailEdit->clear(); m_selectedUserId = -1; m_updateButton->setEnabled(false); m_deleteButton->setEnabled(false); }