第六章 数字软键盘的实现
上一节中给大家讲解了什么是信号和槽的概念以及如何使用信号和槽。这一节中给大家讲解QSignalMapper类,这个类的如何使用,然后使用QSignalMapper实现一个数字软键盘。
我们在使用Qt的过程中可能会遇到这样的情况。
想要在连接的时候传递一个值,像下面这样,不过这样的语法是错误的,连接的过程中不允许参数不匹配。
connect(key, SIGNAL(clicked()), this, SLOT(keyPressed(1)));
比如下面的数字键盘,我们想通过按一个键发送一个值。
我们可以有多个方案实现。下面分别说明:
方案1:使用多个槽函数
方案2:重写类添加信号
通过重新写QPushButton,然后添加信号。
signals:
void clicked(int);
然后按照如下方式使用
QIntPushButton *b;
b=new QIntPushButton(1);
connect(b, SIGNAL(clicked(int)), this, SLOT(keyPressed(int)));
b=new QIntPushButton(2);
connect(b, SIGNAL(clicked(int)), this, SLOT(keyPressed(int)));
这样同样可以实现上面的要求,可是这两个方案比较一下看看他们的优缺点
方案1创建多个槽
-
很多插槽包含几乎相同的代码
-
很难维护(一个很小的改变将改变很多代码)
-
很难扩展(每一个都创建新的槽)
方案2重写类添加信号
-
专有的额外类,很难重用
-
很难扩展(新的子类是针对特殊场景)
QSignalMapper 类能够解决这个问题,下面我们看一下如何使用QSignalMapper实现上面的功能。
信号映射器将一个值与每个按钮关联。这些值被映射
当一个值被映射,信号映射器发出的 mapped(int) 信号,携带的关联的值
基本使用如下:
QSignalMapper *m = QSignalMapper(this);
QPushButton *b;
b=new QPushButton("1");
connect(b, SIGNAL(clicked()),
m, SLOT(map()));
m->setMapping(b, 1);
...
connect(m, SIGNAL(mapped(int)), this, SLOT(keyPressed(int)));
-
示例程序:
创建一个工程,然后添加一个calc类(类名应为大写,这里创建的时候一着急,写成了小写,大家不要范这样的错误),编辑界面如下
然后在calc类中添加如下代码,主要是在构造函数中添加一个QSignalmapper,然后把按键和信号映射器map()相连,为了能够把按键的值传递给文本框,我们创建一个信号keyNum(int)。
calc::calc(QWidget *parent) :
QDialog(parent),
ui(new Ui::calc)
{
ui->setupUi(this);
QSignalMapper *m = new QSignalMapper(this);
connect(ui->buttonZero,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonOne,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonTwo,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonThree,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonFour,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonFive,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonSix,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonEight,SIGNAL(clicked()),m,SLOT(map()));
connect(ui->buttonNine,SIGNAL(clicked()),m,SLOT(map()));
m->setMapping(ui->buttonZero,0);
m->setMapping(ui->buttonOne,1);
m->setMapping(ui->buttonTwo,2);
m->setMapping(ui->buttonThree,3);
m->setMapping(ui->buttonFour,4);
m->setMapping(ui->buttonFive,5);
m->setMapping(ui->buttonSix,6);
m->setMapping(ui->buttonSeven,7);
m->setMapping(ui->buttonEight,8);
m->setMapping(ui->buttonNine,9);
connect(m,SIGNAL(mapped(int)),this,SLOT(keyPress(int)));
}
calc::~calc()
{
delete ui;
}
void calc::keyPress(int i){
emitkeyNum(i);
}
在Dialog中创建一个calc的实例,然后连接它的信号到自定义的槽中,这样就可以把按键的值传递出来了。
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
cal = new calc(this);//创建一个按键类的实例
connect(cal,SIGNAL(keyNum(int)),this,SLOT(set_text(int)));//把按键的值通过信号传递出来
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
cal->show();
}
void Dialog::set_text(int i){
ui->lineEdit->setText(QString().number(i));
}
程序运行如下:
本节给大家讲解了在连接中携带一个值,这里主要介绍的是QSignalMapper类的使用方法。
下一节中将给大家讲解如何自定义Widget,编写自己的窗口小部件。敬请关注。
欢迎加入QQ群:217054129
QQ群:142241185
共同学习嵌入式