Qt-信号映射器

来源:互联网 发布:win10网络修复工具 编辑:程序博客网 时间:2024/05/02 05:06

          在程序中,通常一个按键被点击时,都会自动调用其相应的槽函数,这就不可避免地需要为每个按键定义一个槽函数。而当这些按键功能相近时,可以考虑使用一个槽函数来响应所有的按键点击信号,这可以避免定义过多的槽函数带来的累赘。但这产生了一个问题,即当多个信号与同一槽函数相连接,在信号触发时,槽函数并不能识别信号究竟是哪个按键触发的。

          以下程序展示一个数字键盘来阐述信号映射的原理:


numerickeypad.h

#ifndef _NUMERICKEYPAD_H_#define _NUMERICKEYPAD_H_#include <QWidget>class QPushButton;class QLineEdit;class NumericKeypad : public QWidget{    Q_OBJECT     public:    NumericKeypad( QWidget * = 0 ); private slots:    void keyClicked( const QString & );    void setText( const QString & ); signals:    void textChanged( const QString & );     private:    QList< QPushButton * > keys;    QList< QString > allKeySymbol;    QString m_text;    QLineEdit *lineEdit;};#endif 

          

          为创建数字键盘,通常的做法是将所有的按键放在 QGridLayout中:

  layout->addWidget( key1, 0, 0 );  layout->addWidget( key2, 0, 1 );  ...  layout->addWidget( key0, 3, 1 );  layout->addWidget( keyClear, 3, 2 );
          另一种做法则便捷一些,将与按键相对应的所有 QString保存在QList< QString > 对象allKeySymbol中。再利用循环将按键加进QGridLayout中。

 ...  for( int r = 0; r < 4; ++r )    for( int c  = 0; c < 3; ++c )    {       QString keySymbol = allKeySymbol.at( r * 3 + c );       QPushButton *key = new QPushButton( keySymbol );       layout->addWidget( key, r, c );       keys.append( key );       ...    } ...
           其中,keysQList< QPushButton * >对象,用来保存所有的按键。


完整的代码:

numerickeypad.cpp

#include "numerickeypad.h"#include <QtGui>NumericKeypad::NumericKeypad( QWidget *parent )    :QWidget( parent ){    allKeySymbol << "1" << "2" << "3"                 << "4" << "5" << "6"                 << "7" << "8" << "9"                 << "." << "0" << "C";        QGridLayout *layout = new QGridLayout;    QSignalMapper *mapper = new QSignalMapper( this );        for( int r = 0; r < 4; ++r )        for( int c  = 0; c < 3; ++c )        {            QString keySymbol = allKeySymbol.at( r * 3 + c );            QPushButton *key = new QPushButton( keySymbol );            keys.append( key );            layout->addWidget( key, r, c );            mapper->setMapping( key, keySymbol );        }       foreach( QPushButton *key, keys )        connect( key, SIGNAL( clicked() ), mapper, SLOT( map() ) );        connect( mapper, SIGNAL( mapped( QString ) ),             this, SLOT( keyClicked( QString ) ) );    lineEdit = new QLineEdit;    lineEdit->setAlignment( Qt::AlignRight );    lineEdit->setReadOnly( true );        QVBoxLayout *mainLayout = new QVBoxLayout( this );    mainLayout->addWidget( lineEdit );    mainLayout->addLayout( layout );}void NumericKeypad::keyClicked( const QString &newText ){    if( newText == "C" )        setText( "" );    else        setText( m_text + newText );}void NumericKeypad::setText( const QString &text ){    if( text == m_text )        return;    m_text = text;    lineEdit->setText( text );        emit textChanged( m_text );}

         创建按键的信号映射:

  • 调用QSignalMappersetMapping( QObject *, const QString & )函数,将按键与相应的QString映射起来。
  • 在所有按键与QString的映射建立起来之后,将按键的clicked()信号与QSignalMappermap()槽函数连接。
  • QSignalMappermapped( const QString & )信号与this的槽函数keyClicked( const QString & )连接。

          当某一按键被点击时,其clicked()信号发送时,导致QSignalMapper的槽函数map()被调用,这将会引起QSignalMapper的信号mapped( const QString &)被发送,这个信号将与按键对应的QString对象作为参数发送给thiskeyClicked( const QString & )槽函数。这样,keyClicked就能根据接收到的QString的内容来判断发送信号的是哪一个按键了。

          当按下的键是 C 时,将会清空QLineEdit显示的文本。

main.cpp

#include "numerickeypad.h"#include <QApplication>int main(int argc, char **argv ){    QApplication app( argc, argv );    NumericKeypad keypad;    keypad.show();        return app.exec();}



0 0
原创粉丝点击