Russian Qt Forum

Qt => Общие вопросы => Тема начата: chipset от Июнь 27, 2007, 09:35



Название: Замещение нескольких сигналов одним слотом
Отправлено: chipset от Июнь 27, 2007, 09:35
Здравствуйте подскажите как...
хоть и нашёл на http://qt.osdn.org.ua/signalmapper.html, не получилось
имеем:
}
Код:

//создаём 44 кнопки
QToolButton *toolButton_m1[44];
for (int i=0; i<44; i++)
{
toolButton_m1[i] = new QToolButton(widgetMap);
toolButton_m1[i]->setGeometry(QRect(250+(i*16), 43-i, 13, 3+i));

connect(toolButton_m1[i], SIGNAL(clicked()), this, SLOT(toolButton_m1_0_clicked()));
}

Как сделать универсальный слот, чтобы он мог понимать с какой кнопки нажато...
и в зависимости от кнопки делать что нибудь...
Если есть пример, буду очень рад!


Название: Замещение нескольких сигналов одним слотом
Отправлено: pakulo от Июнь 27, 2007, 10:47
А я могу еще добавить пару способов )))
Есть такой сигнал void triggered ( QAction * action )
Создаешь массив QAction, присваиваешь каждой кнопке свой экшен, а потом уже в методе проверяешь типа
for (int = 0; i < 44; i++)
{
    if (actions = action)
        emit ButtonClicked(i);
}

А можно и так:
В методе toolButton_m1_0_clicked()
получаешь глобальную позицию курсора, отнимаешь позицию формы, что бы получить позицию курсора в твоей форме...
и в слоте toolButton_m1_0_clicked() проверяешь принадлежит ли курсор кнопке по циклу, ну типа
for (int = 0; i <44; ++i)
{
    if (but->geometry().contains(mousePos))
        emit buttonClicked(i);
}

добавлено спустя 2 минуты:

 А что именно у тебя не получилось с тем что описано в доке?
Попробуй способ "Решение с помощью QSignalMapper"


Название: Замещение нескольких сигналов одним слотом
Отправлено: Racheengel от Июнь 27, 2007, 11:12
actionGroup() уже некруто? :)


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: Steven_Orko от Июнь 27, 2007, 11:32
Цитата: "chipset"

Как сделать универсальный слот, чтобы он мог понимать с какой кнопки нажато...
и в зависимости от кнопки делать что нибудь...
Если есть пример, буду очень рад!


Читайем Assistant:
Цитата: ""

QObject * QObject::sender () const   [protected]
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; otherwise it returns 0. The pointer is valid only during the execution of the slot that calls this function.
The pointer returned by this function becomes invalid if the sender is destroyed, or if the slot is disconnected from the sender's signal.
Warning: This function violates the object-oriented principle of modularity. However, getting access to the sender might be useful when many signals are connected to a single slot.

See also QSignalMapper.


Код:

void My_MainWindow::my_universal_slot_for_buttons(void)
{
         //Получаем указатель, на кнопку, которая послала сигнал
         QPushButton* pButton = (QPushButton*) sender();
         if (NULL != pButton)
         {//Если вдруг слот не вызвался сам по себе, а по сигналу, то
              if (pMy_First_Button == pButton)
             {
              }
              if (pMy_seconf_Button = pButton)
               {
               }

         } //if (NULL != pButton)
}


Название: Замещение нескольких сигналов одним слотом
Отправлено: pastor от Июнь 27, 2007, 12:40
Можно ещё заюзать QButtonGroup

Код:

QButtonGroup *btnGrp = new QButtonGroup(this);
//создаём 44 кнопки
QToolButton *toolButton_m1[44];
for (int i=0; i<44; i++)
{
      toolButton_m1[i] = new QToolButton(widgetMap);
      toolButton_m1[i]->setGeometry(QRect(250+(i*16), 43-i, 13, 3+i));
      btnGrp->addButton(toolButton_m1[i]);
}

connect(btnGrp, SIGNAL(buttonClicked( QAbstractButton *)), this, SLOT(toolButton_m1_0_clicked( QAbstractButton *)));


Название: Замещение нескольких сигналов одним слотом
Отправлено: chipset от Июнь 27, 2007, 13:05
Цитата: "pastor"
Можно ещё заюзать QButtonGroup

Код:

QButtonGroup *btnGrp = new QButtonGroup(this);
//создаём 44 кнопки
QToolButton *toolButton_m1[44];
for (int i=0; i<44; i++)
{
      toolButton_m1[i] = new QToolButton(widgetMap);
      toolButton_m1[i]->setGeometry(QRect(250+(i*16), 43-i, 13, 3+i));
      btnGrp->addButton(toolButton_m1[i]);
}

connect(btnGrp, SIGNAL(buttonClicked( QAbstractButton *)), this, SLOT(toolButton_m1_0_clicked( QAbstractButton *)));

а слот как должен выглядеть?


Название: Замещение нескольких сигналов одним слотом
Отправлено: pastor от Июнь 27, 2007, 13:18
Цитата: "chipset"

а слот как должен выглядеть?


К примеру так:

Код:
void My_MainWindow::toolButton_m1_0_clicked(QAbstractButton *pressedButton) 
{
       QToolButton *btn = qobject_cast<QToolButton *>(pressedButton);
       <do something with btn>
}


Название: Замещение нескольких сигналов одним слотом
Отправлено: chipset от Июнь 28, 2007, 07:32
Цитата: "pastor"
Цитата: "chipset"

а слот как должен выглядеть?


К примеру так:

Код:
void My_MainWindow::toolButton_m1_0_clicked(QAbstractButton *pressedButton) 
{
       QToolButton *btn = qobject_cast<QToolButton *>(pressedButton);
       <do something with btn>
}

У меня не получается. т.к. начинающий (ещё и тупой :roll:  ) ..
У меня не получается сделать слот, в котором я могу видить на какую кнопку нажали... допустим.. если нажали на toolButton_m1[1] тогда ...
Как это реализовать, не подскажите?


Название: Замещение нескольких сигналов одним слотом
Отправлено: Steven_Orko от Июнь 28, 2007, 09:15
Код:

void My_MainWindow::toolButton_m1_0_clicked(QAbstractButton *pPressedButton)
 {
        QToolButton *pBtn = qobject_cast<QToolButton *>(pPressedButton);
        if ((NULL != pBtn) && (toolButton_m1[1]  == pBtn)
        {
             QMessageBox::critical(NULL, "Паника!!!!", "Кто-то нажал на кнопку toolButton_m1[1].");
        }
 }



Название: Замещение нескольких сигналов одним слотом
Отправлено: chipset от Июнь 28, 2007, 10:34
Цитата: "Steven_Orko"
Код:

void My_MainWindow::toolButton_m1_0_clicked(QAbstractButton *pPressedButton)
 {
        QToolButton *pBtn = qobject_cast<QToolButton *>(pPressedButton);
        if ((NULL != pBtn) && (toolButton_m1[1]  == pBtn)
        {
             QMessageBox::critical(NULL, "Паника!!!!", "Кто-то нажал на кнопку toolButton_m1[1].");
        }
 }


Всё работает, спасибо большое


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: KocMak от Декабрь 04, 2011, 18:03
Здравствуйте.

Прошу помощи для решения подобной проблемы.

Есть несколько кнопок с метками btStart, btStop... При нажатии на кнопки надо вызывать один слот, но, в зависимости от нажатой кнопки, передавать разное значение переменной command.
Я новичок в написание программ на Qt, да и вообще на ООП, но есть опыт программирования на структурном С. Поэтому я написал примерно так:

Код:
int command=0;
int newcommand=0;


connect(btStart, SIGNAL(clicked()), this, SLOT(SendCommand(1))); //Если нажата кнопка btStart вызвать "SendCommand" и передать "command=1"
connect(btStop, SIGNAL(clicked()), this, SLOT(SendCommand(2)));
...


void MaimWindow::SendCommand(int command)
{
  newcommand=command; //Например
}

Подскажите, пожалуйста, как реализовать такую конструкцию на Qt? Спасибо.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: kambala от Декабрь 04, 2011, 18:34
нет, это неправильно. у слота не может быть параметров больше, чем у сигнала.

есть несколько способов достичь желаемого результата, и, пожалуй, самый оптимальный из них для количества кнопок > 2 - использование QSignalMapper. в документации к этому классу есть отличный пример (и как раз про кнопки).

да, и, как по мне, прежде, чем лезть в приложения "с окошками", неплохо бы просто разобраться с С++ и ООП на примере консольных приложений.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: KocMak от Декабрь 04, 2011, 20:37
Спасибо за помощь, буду разбираться с QSignalMapper.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: FreeSlave от Декабрь 15, 2011, 18:43
У меня похожий вопрос.

Есть массив кнопок, есть несколько методов. Нужно, чтобы при нажатии на каждую из кнопок вызывалась определенная функция (у каждой кнопки - своя). Хотелось бы присоединить в цикле, но не знаю, что делать со SLOT( ), ведь туда нужно посылать название функции, а у них имена разные.

Конечно, можно унаследовать класс кнопки, посылать в каждую свой указатель на функцию, и переопределить нажатие на выполнение данной функции (вместо высылки сигнала), но возможно ли реализовать вышеизложенное без создания новых классов?


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: kambala от Декабрь 15, 2011, 20:01
раз все слоты разные, то напрямую посоединять каждую кнопку с нужным слотом. ну или временно создать массив указателей на методы (слоты) и законнектить все в цикле.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: FreeSlave от Декабрь 15, 2011, 20:38
Массив указателей пробовал, не выходит. Слот вообще похоже не указатель получает, а каким-то неведомым образом находит функцию по названию.

Писал что-то наподобие
Код:
connect(buttons[i], SIGNAL(clicked()), this, SLOT(rotations[i]()) );
и с разыменовыванием и без.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: LisandreL от Декабрь 15, 2011, 20:48
В слоте [ i ] лишнее.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: FreeSlave от Декабрь 15, 2011, 21:16
Это массив указателей на функции. [ i ] - обращение к i-тому элементу.


Название: Re: Замещение нескольких сигналов одним слотом
Отправлено: LisandreL от Декабрь 15, 2011, 21:55
Это массив указателей на функции. [ i ] - обращение к i-тому элементу.
Так не получится. Слот это слот. То что в классе через public/private/protected slots: объявлено.
Просто функция слотом быть не может.
Делайте слот с параметром i, конектитесь через QSignalMapper (см. справку в как), а уже в слоте вызывайте свои функции по индексу.