crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Несколько слотов на 1 кнопке
AD
  опции профиля:
сообщение 22.5.2009, 15:24
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Помогите, пожалуйста, разобраться в следующей ситуации.
Есть кнопка открытия COM-порта. После того, как COM-порт открыт, название кнопки изменяется с "Open" на "Close"! Ну и соответственно при следующем нажатии надо попадать в слот закрытия порта. Как это сделать корректно?

Вот маленький кусок кода:
/// Класс главного окна программы
class ImitatorTSL: public QMainWindow, public Ui::ImitatorTSLClass
{
    Q_OBJECT

private:
    bool isPortNumEmpty();
    int numberPort();
    char* stringPort();

public slots:
    void openPort();
    void closePort();
};

ImitatorTSL::ImitatorTSL(QWidget *parent, Qt::WFlags flags): QMainWindow(parent, flags)
{
    setupUi(this);

    connect(btnPortWorking, SIGNAL(clicked()), this, SLOT(openPort()));
    connect(btnPortWorking, SIGNAL(clicked()), this, SLOT(closePort()));
}

ImitatorTSL::~ImitatorTSL() {}

/// Проверка edit-поля номера порта на пустоту
bool ImitatorTSL::isPortNumEmpty()
{
    if(linePort -> text().isEmpty())
    {
        QMessageBox message(QMessageBox::Critical, QString("Error"), QString("Number of port must not to empty"),
                            QMessageBox::Ok, this);
        message.exec();
        return true;
    }
    return false;
}

/// Возвращает номер порта (если есть неполадки, то -1)
int ImitatorTSL::numberPort()
{
    bool ok;
    int port = linePort -> text().toInt(&ok);
    if(!ok)
    {
        QMessageBox message(QMessageBox::Critical, QString("Error"), QString("Number of port isn't correct"),
                            QMessageBox::Ok, this);
        message.exec();
        return -1;
    }

    return port;
}

/// Получение строкового значения порта
char* ImitatorTSL::stringPort()
{
    int port = numberPort();
    if(port == -1) return "error";
    string port_str(QString(QString("COM") + QString::number(port)).toStdString());
    char *char_numport = new char[port_str.size() + 1];
    memcpy(char_numport, port_str.c_str(), port_str.size());
    char_numport[port_str.size()] = 0;

    return char_numport;
}

/// Открытие порта COM
void ImitatorTSL::openPort()
{
    if(isPortNumEmpty()) return;
    char *char_numport = stringPort();
    if(!_stricmp(char_numport, "error")) return;

    COMPort comPort;
    bool init = comPort.init(::CreateFile(char_numport, GENERIC_READ | GENERIC_WRITE,
        0,        // comm devices must be opened w/exclusive-access
        0,    // no security attributes
        OPEN_EXISTING, // comm devices must use OPEN_EXISTING
        0,        // not overlapped I/O
        0    // hTemplate must be NULL for comm devices
        ));
    if(!init)
    {
        DWORD error = ::GetLastError();
        QMessageBox message(QMessageBox::Critical, QString("Error"), QString("Error number %1").arg(error),
                            QMessageBox::Ok, this);
        message.exec();
        return;
    }
    btnPortWorking -> setText("Close");
}

/// Закрытие COM-порта
void ImitatorTSL::closePort()
{
    char *char_numport = stringPort();
    if(!_stricmp(char_numport, "error")) return;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 22.5.2009, 15:44
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Можно что-то вроде этого сделать.
connect(myButton, SIGNAL(clicked()), this, SLOT(buttonSlot()));

void MyClass::buttonSlot()
{
    if(myButton->text() == "Open")
        closePort();
    else
        openPort();
}


Можно сделать кнопку со свойством setCheckable(true). Ловить сигнал
Цитата
void QAbstractButton::toggled ( bool checked ) [signal]
, и в зависимости от состояния checked, вызывать нужный метод. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 22.5.2009, 16:14
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Спасибо. Нашел еще один вариант.
Код переделан следующим образом:
/// Открытие порта COM
void ImitatorTSL::openPort()
{
    // .....
    btnPortWorking -> setText("Close");
    disconnect(btnPortWorking, SIGNAL(clicked()), this, SLOT(openPort()));
    connect(btnPortWorking, SIGNAL(clicked()), this, SLOT(closePort()));
}

/// Закрытие COM-порта
void ImitatorTSL::closePort()
{
    bool res = com_port.close();
    if(!res) return;
    btnPortWorking -> setText("Open");
    disconnect(btnPortWorking, SIGNAL(clicked()), this, SLOT(closePort()));
    connect(btnPortWorking, SIGNAL(clicked()), this, SLOT(openPort()));
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 22.5.2009, 16:16
Сообщение #4


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


AD, зачем этот постоянный коннект/дисконнект??? ИМХО, не очень хорошо!!!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 22.5.2009, 16:37
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(igor_bogomolov)
ИМХО, не очень хорошо!!!

Почему? Чем disconnect плох?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 22.5.2009, 16:58
Сообщение #6


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(AD @ 22.5.2009, 17:37) *
Чем disconnect плох?
Код становится труднее читать, при таком построении.
Это мое мнение. :rolleyes:

Сообщение отредактировал igor_bogomolov - 22.5.2009, 17:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 22.5.2009, 17:04
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Начитавшись книги "Паттерны проектирования" Влиссидеса, Гамма, Хелма, Джонсона, сделал класс COMPort одиночкой! :)


igor_bogomolov, ну не знаю. А мне нравится. Еще подумаю, может и переделаю. Но так, как-то универсальнее, что-ли, а то, эти if-else достали.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.5.2009, 20:31
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9655
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


AD, я с Игорем согласен. Переподключение сиганалов плохая затея.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 17.9.2019, 8:24