Qt 5 назначить слот с параметрами QPushButton
у меня есть приложение Qt на C++, и я хочу назначить слот QPushButton. Но я хочу передать некоторые аргументы, потому что у меня есть несколько QPushButton, которые делают то же самое, поэтому я хочу одну функцию, но с параметром в ней, но Qt продолжает говорить мне, что нет такого слота. Может кто-нибудь сказать мне, почему и как я должен делать это?
спасибо заранее
в рамках .H-файл у меня есть: (это было в начале, но я изменил его в поиске проблема)
public slots:
void handleButton(int row, int col);
затем в .cpp:
void fieldWindow::handleButton(int row, int col){
cout << row << " " << col << endl;
}
и снова в том же самом .cpp:
connect(this->buttonsField[i][j], SIGNAL(released()), this, SLOT(handleButton(i,j)));
это делается в два вложенных цикла, так i
и j
четко определены.
и моя ошибка:
QObject::connect: No such slot fieldWindow::handleButton(i,j) in ..Proj1fieldwindow.cpp:41
QObject::connect: (receiver name: 'fieldWindow')
Я что-то читал в интернете, что я должен сказать handleButton(int, int);
но тогда как я должен передать аргументы ?
1 ответов
к сожалению, соединение Qt signal-slot не принимает никаких аргументов для передачи в слот при вызове сигнала. Это работает только в том случае, если сам сигнал предоставляет эти аргументы, но вы не можете добавить их в connect
заявление.
но вы не единственный, кто хочет это сделать, поэтому в Qt есть класс, который делает почти что требуется: QSignalMapper
. Экземпляр этого класса можно использовать в качестве "прокси" для соединения сигнал-слот: вы подключите (несколько) кнопок к слоту этого класса и подключите сигнал этого класса к целевому слоту. Затем для каждого экземпляра "отправителя" (в вашем случае кнопки) вы можете указать класс, какое значение добавить в вызываемый слот. Пример:
QPushButton * button1 = ...;
QPushButton * button2 = ...;
QSignalMapper mapper;
connect(button1, SIGNAL(released()), &mapper, SLOT(map()));
mapper.setMapping(button1, 42); // Number to be passed in the slot
connect(button2, SIGNAL(released()), &mapper, SLOT(map()));
mapper.setMapping(button2, 1337); // Number to be passed in the slot
connect(&mapper, SIGNAL(mapped(int)), this, SLOT(handleButton(int)));
к сожалению, как вы можете видеть, этот класс может обрабатывать только один параметр. Для вашего случая вы должны выбрать другой метод (я объяснил выше, если вы снова столкнетесь с подобной проблемой, но с одним int
параметр.)
альтернатива, которая соответствует вашей проблеме полагаться на sender()
в слот. Помните свое отображение в структуре данных, например
QMap<QObject*,int> rows;
QMap<QObject*,int> cols;
и открыть в слот, который занимает аргумент:
void fieldWindow::handleButton(){
int row = rows[sender()];
int col = cols[sender()];
cout << row << " " << col << endl;
}
конечно, при инициализации пользовательского интерфейса, вы должны поместить соответствующие значения в эти карты. Или вы можете найти свою кнопку в существующем массиве buttonsField
.
другой метод существует с Qt5 и C++11: вместо слота вы можете обрабатывать сигналы в лямбда-функции. Это будет выглядеть так (сигнал называется с использованием нового синтаксиса):
connect(this->buttonsField[i][j], &QPushButton::released, [=]{
handleButton(i, j);
});
Если вам не нравится синтаксис лямбда, также можно использовать некоторые помощники из стандартной библиотеки для создания функтора вместо лямбды, или вы можете написать свой собственный класс функтора, но лично я нахожу лямбду очень читаемой.