Здравствуйте, Marty, Вы писали:
M>Здравствуйте!
M>... M>Докопался вроде, что следует использовать QSignalMapper. Но вот нихрена не понял, как это сделать
Для начала нужно понять вашу логику, как вы планируете делать разные действия по одному и тому же хоткею?
А вообще вместо QSignalMapper проще заюзать лямбды с захватом в качестве слота.
M>>... M>>Докопался вроде, что следует использовать QSignalMapper. Но вот нихрена не понял, как это сделать
SaZ>Для начала нужно понять вашу логику, как вы планируете делать разные действия по одному и тому же хоткею?
Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
Похоже, через сигнал-слоты не получится нормально, придется ставить case в оконную процедурупереопределять функцию event
Здравствуйте, Marty, Вы писали:
M>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
Так у вас на каждую кнопку будет свой хоткей тогда =). По тексту различайте. В документации по QSignalMapper есть практически ваш пример. Там хоть инт, хоть стринг принимаются.
P.S. я чуть обновил предыдущее сообщение.
M>Похоже, через сигнал-слоты не получится нормально, придется ставить case в оконную процедурупереопределять функцию event
Можно, но не нужно.
Re[3]: Нужно несколько горячих клавиш повесить на одну функцию
Здравствуйте, Marty, Вы писали:
M>... M>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
Псевдокод:
for ( int i = 0; i <= 9; i++ )
{
auto handler = [=]()
{
std::cout << "hotkey id = " << i;
};
const auto text = QString("%d").arg(i)
QAction *pa = new QAction( QIcon(), text, this );
pa->setShortcut( QKeySequence( /* Qt::CTRL + */ Qt::Key_0 + i) );
connect( pa, &QAction::triggered, handler );
this->addAction(pa);
}
Но если хотите, можно повозиться с QSignalMapper. Хотя я на практике ни разу его не использовал.
Re[4]: Нужно несколько горячих клавиш повесить на одну функцию
Здравствуйте, SaZ, Вы писали: M>>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9 SaZ>Так у вас на каждую кнопку будет свой хоткей тогда =). По тексту различайте. В документации по QSignalMapper есть практически ваш пример. Там хоть инт, хоть стринг принимаются.
этот, что ли
class ButtonWidget : public QWidget
{
Q_OBJECT
public:
ButtonWidget(QStringList texts, QWidget *parent = 0);
signals:
void clicked(const QString &text);
private:
QSignalMapper *signalMapper;
};
The only function that we need to implement is the constructor:
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));
setLayout(gridLayout);
}
Я в сигналах и слотах разбираюсь, как свинья в апельсинах. Так и не понял, как это к QAction прикрутить
SaZ>P.S. я чуть обновил предыдущее сообщение.
А вот с лямбдой — идея неплохая
M>>Похоже, через сигнал-слоты не получится нормально, придется ставить case в оконную процедурупереопределять функцию event SaZ>Можно, но не нужно.
Здравствуйте, Marty, Вы писали: M>Здравствуйте, SaZ, Вы писали: M>>>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9 SaZ>>Так у вас на каждую кнопку будет свой хоткей тогда =). По тексту различайте. В документации по QSignalMapper есть практически ваш пример. Там хоть инт, хоть стринг принимаются. M>
этот, что ли
M>class ButtonWidget : public QWidget
M>{
M> Q_OBJECT
M>public:
M> ButtonWidget(QStringList texts, QWidget *parent = 0);
M>signals:
M> void clicked(const QString &text);
M>private:
M> QSignalMapper *signalMapper;
M>};
M>The only function that we need to implement is the constructor:
M>ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
M> : QWidget(parent)
M>{
M> signalMapper = new QSignalMapper(this);
M> QGridLayout *gridLayout = new QGridLayout;
M> for (int i = 0; i < texts.size(); ++i) {
M> QPushButton *button = new QPushButton(texts[i]);
M> connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
M> signalMapper->setMapping(button, texts[i]);
M> gridLayout->addWidget(button, i / 3, i % 3);
M> }
M> connect(signalMapper, SIGNAL(mapped(const QString &)),
M> this, SIGNAL(clicked(const QString &)));
M> setLayout(gridLayout);
M>}
Он самый. Суть маппера в том, что он ловит сигнал без параметра, потом по отправителю смотрит, что нужно в качестве параметра использовать, потом бросает свой сигнал, но уже с параметром. Такой вот прокси класс, паттерн "посредник". В примере вместо button будет ваш QAction. M>Я в сигналах и слотах разбираюсь, как свинья в апельсинах. Так и не понял, как это к QAction прикрутить
Стоит разобраться, причём хорошо, без этого Qt практически бесполезен. Потому что на Qt-шном эвент лупе и сигналах-слотах строится достаточно удобная событийная модель программирования. M>Без лямбды — был бы самый нормальный вариант
M>>>>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
SaZ>>>Так у вас на каждую кнопку будет свой хоткей тогда =). По тексту различайте. В документации по QSignalMapper есть практически ваш пример. Там хоть инт, хоть стринг принимаются.
SaZ>Он самый. Суть маппера в том, что он ловит сигнал без параметра, потом по отправителю смотрит, что нужно в качестве параметра использовать, потом бросает свой сигнал, но уже с параметром. Такой вот прокси класс, паттерн "посредник". В примере вместо button будет ваш QAction.
Суть я понимаю. Я не понимаю, почему оно не работает
M>>Я в сигналах и слотах разбираюсь, как свинья в апельсинах. Так и не понял, как это к QAction прикрутить
SaZ>Стоит разобраться, причём хорошо, без этого Qt практически бесполезен. Потому что на Qt-шном эвент лупе и сигналах-слотах строится достаточно удобная событийная модель программирования.
Да в обще вроде разобрался, непонятны только два момента какого чорта оно иногда не собирается, выдавая не слишком понятное сообщение, и второй момент — это почему оно собирается, но не работает
M>>Без лямбды — был бы самый нормальный вариант
SaZ>Есть на то реальные причины?
Я имел в виду, что если бы лямбд не было бы, то через переопределение event имхо было бы проще всего. Ну, а так — с лямбдой да, вообще элементарно. Я что-то не подумал, что тут лямбды поддерживаются
Здравствуйте, SaZ, Вы писали:
M>>... M>>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
SaZ>Псевдокод:
this->>addAction(pa);
M>
M>Так работает. Но мне нужно динамически добавлять хоткей на один и тот же обработчик, при этом требуется их различать. M>Обработчик выглядит так: M>
void slotShortcut( int id );
M>События я различаю по ID.
M>Докопался вроде, что следует использовать QSignalMapper. Но вот нихрена не понял, как это сделать
Можно использовать функцию sender внутри обработчика MainWindow::slotShortcut0, что бы понять кто кинул сигнал.
UPD: А когда получил QAction через sender , то можно взять юзерские данные через data(), куда заранее положишь цифры от 1 до 9, как в твоем примере выше.
D>Можно использовать функцию sender внутри обработчика MainWindow::slotShortcut0, что бы понять кто кинул сигнал.
Об этом я позже узнал, но спс.
D>UPD: А когда получил QAction через sender , то можно взять юзерские данные через data(), куда заранее положишь цифры от 1 до 9, как в твоем примере выше.
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, SaZ, Вы писали:
M>>>... M>>>Чего тут понимать — хоткеи разные, например, кнопки 1, 2, 3, ... 9, 0 — вызывается один обработчик с параметром int, который может принимать значения 0 — 9
SaZ>>Псевдокод:
M>Кстати, а как потом расконнектить такое?
QAction *pa = new QAction( QIcon(), text, this );
pa->setShortcut( QKeySequence( /* Qt::CTRL + */ Qt::Key_0 + i) );
connect( pa, &QAction::triggered, handler );
pa->disconnect();//Удалить все коннекты данного QAction