Qt: signal mapping

qt-embeddedЕсли пользовательский интерфейс Qt имеет несколько однотипных элементов управления,  сигналы от них удобно обрабатывать при помощи signal mapping.

Например, есть виджет с 8 checkbox’ами, при помощи которых можно задать битовую маску.

bitwidget

 

Обработка сигналов для каждого из CheckBox’а одинаковая поэтому её проще сделать через signal mapping а не заводить отдельный слот для каждого CheckBox’а.

Для реализации signal mapping d Qt надо выполнить следующие действия:

  1. Указать Id для данного элемента UI при помощи setMapping
  2. Соединить сигнал от элемента UI со слотом map QSignalMapper
  3. Соединить сигнал 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

Запись опубликована в рубрике Qt с метками . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>