C ++ Qt: возможно ли создать своего рода слот для шаблона? - PullRequest
0 голосов
/ 28 ноября 2018

Я новичок в Qt и не эксперт C ++, поэтому, пожалуйста, потерпите меня.Я работаю над приложением, которое имеет 12 различных кнопок QPushButton, но все они выполняют очень похожие действия: они получают какое-то значение с карты, а затем используют его для установки стиля для этой кнопки:

void MainWindow::on_btn01_clicked(){
    QString img=images["btn01"];
    ui->btn01->setStyleSheet("#btn01{ background-image: url(://" + img + ") }");
}

Для каждой из 12 кнопок я должен создать слот, который отличается только используемой кнопкой.Так что выглядит немного странно, если создать 12 практически идентичных функций.

Есть ли лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы можете попробовать еще один простой метод, который устанавливает имя объекта QPushButton соответственно, и проверьте имя объекта в вашем слоте и используйте эту строку.Это экономит вам много кода.

Пример:
Имя объекта QPushButton 1 установлено как button->setObjectName("btn01");, и, соответственно, вы можете установить другие имена кнопок, и в вашем слоте вы можете сделать что-то вроде этого

void MainWindow::on_button_clicked(){
     QPushButton* btn=qobject_cast<QPushButton*>(sender()); 
     QString name=btn->objectName(); 
     QString img=images[name]; btn->setStyleSheet("#" + name + "{ background-image: url(://" + img + ");
}

и затем подключите все свои QPushButtons к этому слоту

0 голосов
/ 28 ноября 2018

Как правило, я видел несколько подходов:

  1. Предпочтительный метод: лямбда-выражения.

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

    Я ожидаю, что полученный код будет выглядеть примерно так:

    foreach( QPushButton * button : buttons ) {
      connect( button, &QPushButton::clicked, [button, &images]() {
        button->setStyleSheet( QString( "{ background-image: url(://%1) }" )
          .arg( images[button->objectName()] ) );
      });
    }
    

    Смотрите " Слоты Qt и лямбда-код C ++ 11 " для получения дополнительной информации о том, как писать лямбда-функции с помощью Qt.

  2. Более грязный способ: QObject :: sender ().

    Qt позволяет вам использовать QObject :: sender () внутри слота, чтобы получить указатель на объект, который его вызвал.Этот подход широко использовался в течение многих лет, но есть ограничения, как описано в документации Qt:

    Предупреждение: Как упоминалось выше, возвращаемое значение этой функции недопустимо, когда слотвызывается через Qt :: DirectConnection из потока, отличного от потока этого объекта.Не используйте эту функцию в сценариях этого типа.

    См. " Как получить виджет отправителя с механизмом сигнала / слота? " для получения дополнительной информации.

  3. Устаревший код: QSignalMapper.

    Существует класс QSignalMapper , который позволит вам связать сигнал с битом данных, например строкой, чтобы затем подключиться кслот, который использует этот параметр.Раньше он существовал как вспомогательный класс в Qt, но постепенно исключается из-за того, что методика лямбда делает его бессмысленным.

    Если вам нужно обновить код, использующий QSignalMapper, для его удаления, это руководство является разумной отправной точкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...