Если пользовательский интерфейс Qt имеет несколько однотипных элементов управления, сигналы от них удобно обрабатывать при помощи signal mapping.
Например, есть виджет с 8 checkbox’ами, при помощи которых можно задать битовую маску.
Обработка сигналов для каждого из CheckBox’а одинаковая поэтому её проще сделать через signal mapping а не заводить отдельный слот для каждого CheckBox’а.
Для реализации signal mapping d Qt надо выполнить следующие действия:
- Указать Id для данного элемента UI при помощи setMapping
- Соединить сигнал от элемента UI со слотом map QSignalMapper
- Соединить сигнал mapped от QSignalMapper со слотом, который будет на основе id выполнять обработку
Id может быть нескольких типов:
- int
- QString
- QWidget
- QObject
Пример использования signal mapping в Qt.
Описание класса BitWidget:
class BitWidget: public QWidget { Q_OBJECT QList< QCheckBox*> _checkList; //список из указателей на QCheckBox int _bitMask; //битовая маска public: BitWidget(); //конструктор int bitMask(); //метод для получения маски private slots: void changeBit( int id ); }; |
Конструктор класса BitWidget
BitWidget::BitWidget() : QWidget(), _bitMask(0) { QSignalMapper *signalMapper = new QSignalMapper(this); //создаем signal mapper QHBoxLayout *layout = new QHBoxLayout; //layout в котором будут находиться CheckBox'ы for( int id=0; id < 8; id++ ) { //создаем 8 CheckBox'ов QCheckBox *checkBox = new QCheckBox; checkBox->setText( QString("Bit %1").arg(id) ); _checkList << checkBox; //добавляем в список layout->addWidget( checkBox ); //добавляем в layout //устанавливаем что когда будет приходить сигнал от данного checkBox'а //то будет генерироваться сигнал mapped с указанным id signalMapper->setMapping( checkBox, id ); //соединяем сигнал от CheckBox'a со слотом signalMapper'a connect( checkBox,SIGNAL(clicked()),signalMapper,SLOT(map())); } //соединяем сигнал mapped со слотом changeBit виджета connect(signalMapper, SIGNAL(mapped(int)), this, SLOT( changeBit(int))); setLayout(layout); } |
Слот changeBit
void BitWidget::changeBit( int id ) { //определяем выставлен ли CheckBox с указанным id if( _checkList.at(id)->isChecked() ) { _bitMask |= (1<<i); } else { _bitMask &= ~(1<<i); } qDebug() << _bitMask; } |
Исходники выложил на github