Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Один слот для разных действий 
:(
    Опции темы
nullpoint
Дата 18.10.2014, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 4.6.2013

Репутация: нет
Всего: нет



Всем привет. Подскажите как правильнее сделать.
 Есть небольшое приложение. Создаю сокет, авторизуюсь на сервере и отсылаю серверу команду. В зависимости от содержания ответа сервера выполняю действия. Проблема в том, что команда серверу может отсылаться автоматически по срабатыванию таймера, а также при нажатии на кнопку на форме. Если команда отсылается автоматически и в ответе сервера есть необходимые данные выполняются одни действия, а если нажимается кнопка и ответ сервера нас удовлетворяет, то другие. 
 Сейчас реализовал это таким образом: завел глобальную переменную, если нажмается кнопка приравниваю переменную единице, если автоматически отсылается команда - приравниваю двойке. Как более правильно реализовать данный функционал?
Код

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTcpSocket>
#include <QTimer>
#include <QMessageBox>
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    con = 0;
 
    socks = new QTcpSocket(this);
 
    auth += "Action: login\r\nUsername: auth\r\nSecret: auth\r\nEvents: off\r\n\r\n";
    com += "Action: Command\r\nCommand: core show channels\r\n\r\n";
 
    connect(socks,SIGNAL(readyRead()),this,SLOT(readCom()));
    tim = new QTimer();
    connect(tim,SIGNAL(timeout()),this,SLOT(deactivateDelivery()));
    tmr = new QTimer();
    tmr->start(5000);
    connect(tmr, SIGNAL(timeout()),this,SLOT(auto_com()));
}
 
MainWindow::~MainWindow()
{
    delete ui;
    if (con == 1)
        socks->disconnectFromHost();
}
 
void MainWindow::on_pushButton_clicked()
{
    socks->connectToHost("localhost",5038);
    if ( socks->waitForConnected(5000) )
    {
        con = 1;
        ui->label->setText("Connected");
    }
    socks->write(auth);
}
 
void MainWindow::on_pushButton_2_clicked()
{
    int k;
    k = QMessageBox::question(0,"Quest","???",trUtf8("Ok"),trUtf8("No"),0,1);
    switch(k)
    {
    case 0:
        socks->write(com);
        kl=1;
    case 1:
        break;
    }
}
 
void MainWindow::readCom()
{
    QRegExp reg_exp("(\\d+) active call");
 
    while (socks->bytesAvailable())
        com_read.append(socks->readAll());
 
    ui->textBrowser->setText(com_read.data());
 
    int n = reg_exp.indexIn(com_read.data());
    if (n != -1)
    {
            if (reg_exp.cap(1).toInt() != 0)
            {
               tim->start(15000);
            }
            else
            {
                if (kl==1)
                {
                    tim->stop();
                    QMessageBox::information(0,"Info","Ok");
                    kl=0;
                }
                else if (kl==2)
                {
                    tim->stop();
                    QMessageBox::information(0,"Info","LoL");
                    kl=0;
                }
            }
    }
 
    com_read.clear();
}
 
void MainWindow::on_pushButton_3_clicked()
{
    socks->disconnectFromHost();
    ui->label->setText("Disconnected");
}
 
void MainWindow::deactivateDelivery()
{
    socks->write(com);
}
 
void MainWindow::auto_com()
{
    kl=2;
    socks->write(com);
}


Код

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTcpSocket>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_pushButton_clicked();
 
    void on_pushButton_2_clicked();
    void readCom();
 
    void on_pushButton_3_clicked();
    void deactivateDelivery();
    void auto_com();
 
signals:
    void active_call(int);
 
private:
    Ui::MainWindow *ui;
    int con;
    QTcpSocket *socks;
    QByteArray auth;
    QByteArray com;
    QByteArray *auth_read;
    QByteArray com_read;
    QByteArray auth_buf;
    QByteArray com_buf;
    QRegExp reg_exp;
    QTimer *tim;
    QTimer *tmr;
    int kl;
};
 
#endif // MAINWINDOW_H

Еще хотел бы разобраться с авторизацией и разбором ответа от сервера. Сейчас после авторизации нет проверки прошла ли авторизация успешно. В случае успешной авторизации от сервера приходит ответ Response: Success. Как использовать слот и для разбора ответа на авторизацию и для разбора ответа на команду. Сейчас приходит в голову только такой же вариант с переменной: при отправке команды авторизации приравнивать ее какому-нибудь числу, в слоте смотреть чему она равна и в зависимости от этого делать разбор авторизации или ответа на другую команду, а затем переменную обнулять. Но как я говорил, мне кажется это плохая идея.
PM MAIL   Вверх
Vasya
Дата 19.10.2014, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

Репутация: нет
Всего: нет



Может случиться так, что автоматическая отправка и нажатие кнопки совпадут и глобальная переменная тут теряет смысл. Мне кажется, при срабатывании таймера и при нажатии на кнопку нужно создавать новое подключение, соответственно соединить сигналы чтения из сокета с разнымы слотами. И там , после получения ответа, удалить сокет.  И никаких глобальных переменных.
Например, для авторизации создаем новое соеденение, соеденяем сигнал чтения из сокета с слотом обработки ответа запроса на авторизацию, передаем пароль, ждем ответа, обрабатываем ответ, удаляем сокет.

Это сообщение отредактировал(а) Vasya - 19.10.2014, 22:00
PM MAIL   Вверх
math64
Дата 20.10.2014, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Альтернатива тому, что сделано - обрабатывать чтение сокета в отдельной нити вместо таймеров.

Боле ивилизованно текущую версию программы можно оформить как автомат состояний, т.е. вместо int k1:
Код

enum State { Init, ByButton, ByTimer } m_state;

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0414 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.