Передать несколько аргументов в слот

В настоящее время я работаю над игрой с моим другом, и теперь мы застряли. Нам нужно передать два аргумента в слот. Я хочу использовать один слот для двух кнопок, и одна из кнопок будет использоваться для добавления, а другая для вычитания. Это будет один из аргументов: 0 (для вычитания) или 1 (для сложения). Другой аргумент будет своего рода идентификатором, потому что у меня будет несколько наборов этих двух кнопок. Я использовал несколько других слотов в своем коде, и на этих слотах я использовал QSignalMapper следующим образом:

Button * button = new Button(argument1, argument2, argument3);

int num = 1;

QSignalMapper * signalMapper = new QSignalMapper(this);

connect(button, SIGNAL(clicked()), signalMapper, SLOT(map)));
signalMapper->setMapping(button, num);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(mySlot(int)));

scene->addItem(button);

Есть ли способ передать два аргумента в слот?

3 ответа

Использовать sender() функция вместо:

void mySlot()
{
    if (sender() == addButton)
        ...
    else
        ...
}

В вашем случае вы можете удалить int аргумент от mySlot и сделайте следующее:

 connect(addButton, SIGNAL(clicked()), someObject, SLOT(mySlot()));
 connect(subButton, SIGNAL(clicked()), someObject, SLOT(mySlot()));

Затем используйте sender Функция для определения источника.

Для прямого ответа на ваш вопрос, да, вы можете определить слот, который принимает до 8 аргументов (до C++11) или любое число (C++11 или позже). Проблема в том, что они должны быть подключены к сигналу с таким же или большим количеством параметров.

Пример, если у вас есть сигнал с подписью notify(int, bool, QString) Вы можете подключить его к слоту с любой из следующих подписей:

  • someSlot(int)
  • someSlot(int, bool)
  • someSlot(int, bool, QString)

QSignalMapper имеет только один параметр. Но вы можете использовать один из следующих способов, чтобы разделить кнопки на несколько наборов:

  • начинать каждый ID набора с известного номера, то есть первый набор начинается с 100, второй набор с 200 и т. д., и вы можете легко определить набор, разделив число на 100: 102 обозначает первый набор и ID кнопки = 2;
  • использовать сопоставление с QString где вы можете использовать некоторый токен, чтобы отделить номер набора от номера кнопки, т.е. 1;2 (первый набор, кнопка ID = 2) с помощью QString::split(),

Пример слота:

void mySLot (const QString& id)
{
    QStringList tokens = id.split (";");

    if (tokens.count () == 2) {
        int setId    = tokens.at(0).toInt ();
        int buttonId = tokens.at(1).toInt ();

        /* Your code goes here */
    }
}

[полностью пересмотренный ответ]

Итак, у нас есть объект Button с несколькими аргументами, которые необходимо передать в слот.

class Button
{
   Q_OBJECT
 public:
   int m_arg1, m_arg2, m_arg3;

   Button(int arg1, int arg2, int arg3)
   {
      m_arg1 = arg1;
      m_arg2 = arg2;
      m_arg3 = arg3;
   };

   /// some function that emits a click signal with 2 of my arguments
   void doSomething()
   {
       emit clicked (m_arg2, m_arg3);
   }

 signals:
   void clicked(int, int);
};

Затем, позже:

Button *button = new Button(val1, val2, val3);
connect(button, SIGNAL(clicked(int, int)), this, SLOT(mySlot(int, int)));

MyReceiver::mySlot(int a1, int a2)
{
  // see who called me, then use arguments
  if (addButton == sender())
  {
     x = a1 + a2;
  }
  else if (subButton == sender())
  {
     x= a1 - a2;
  }
}
Другие вопросы по тегам