QT ① 概述&信号与槽
一、概述
- 优良的跨平台特性
- 面向对象:其中信号与槽替代了回调函数,更加安全(会进行类型检查等)
- 丰富的API
- 大量的开发文档
二、命令行程序
qmake:
Makefile 生成器,能根据工程文件(.pro)产生不同平台下的Makefileuic:
把ui文件自动生成相应的C++代码
三、QString类
示例代码:
qDebug() << "hello world"; int a = 10 , b = 20; //C++ 风格 qDebug() << "a = " << a << " , b = " << b; //C语言风格 qDebug("a = %d , b = %d",a,b); //QString qt中的字符串类 QString str1 = "12345"; QString str2("welcome"); qDebug() << str1 << " " << str2; //qstring 转换 为Int 类型 int c = str1.toInt(); qDebug() << c; QByteArray arr = str1.toUtf8(); qDebug() << arr; //QString 的 arg():可以将任意类型的数据转换为 QString 类型 QString str3 = QString("a: %1, b: %2 , c: %3").arg(a).arg(b).arg(c); qDebug() << str3; //number():将数值数据转换为QString str3 = QString::number(a); qDebug() << str3; QString str4 = "QString 44444"; qDebug() << str4.right(2); //right(n) 取出字符串右边有多少个字符 qDebug() << str4.left(2); //取出左边 qDebug() << str4.mid(2); //取出中间 QString str5 = "123,456,789"; QStringList list = str5.split(","); //将字符串分割(以逗号分割开) qDebug() << list; //字符串List容器 qDebug() << list[0] << " " << list[2];
输出结果:
hello world a = 10 , b = 20 a = 10 , b = 20 "12345" "welcome" 12345 "12345" "a: 10, b: 20 , c: 12345" "10" "44" "QS" "tring 44444" QList("123", "456", "789") "123" "789"
四、QT工作原理(事件驱动、信号与槽机制)
1、事件:
UI界面或者控件上发生的任何事情,被称为事件。
如:鼠标移动、鼠标点击、控件移动、键盘按压、定时器等,都可以被称为事件触发
2、信号(signals):
信号是一个不完整的函数(
只有声明,没有定义
)。一般由系统类库提供,或者由程序员在类体的
signals区域声明
。信号可以是
事件驱动触发
、也可以是程序员代码中手动emit触发
。3、槽函数(slots):
- 是一个完整的成员函数(
既有声明,又有定义
)。一般由系统类库提供
,或者是程序员手动声明在类体的权限区域的slots区域声明
。- 槽函数可以是信号触发后,
系统自动调用
,也可以是程序员在函数中手动调用
。4、事件驱动:
- UI界面或者控件上产生的任何事情,都会触发
一个或者多个
信号。5、信号与槽机制:
- 将信号与某个槽函数进行
关联(绑定、注册)
,当信号被触发,系统自动调用
关联的槽函数。6、信号与槽的绑定:
(1)方法一:ui设计器,鼠标右键转到槽
槽函数语法:
void on_objectName_signal();
- (2)方法二:connect函数,手动绑定
/* * 旧风格绑定信号与槽 * * connect(const QObject *sender, const char *signal, const QObject *receiver, const char*member); * 功能: * 将sender的signal信号 与 receiver的member槽函数关联 * 参数: * sender:信号触发者首地址 * signal:触发的信号首地址 * receiver:信号的接收者首地址(槽函数所在的类对象) * member: 要绑定的槽函数首地址 */ connect(ui->oldone , SIGNAL(clicked(bool)) , this , SLOT(btn_clicked())); /*新风格绑定 * 安全性更高 * 信号与槽函数都有类型的说明 */ connect(ui->newone , &QPushButton::clicked , this , &SignalSlots::btn_clicked_new); /* * 匿名函数绑定 * [] 表示函数名 ()参数列表 {} 函数体 * & 引用符,表示匿名函数中引用外部的所有成员 * = 表示匿名函数中拷贝外部的所有成员 */ connect(ui->someone , &QPushButton::clicked , this , [&](){ qDebug() << "匿名绑定"; speaker.say("哈基米喔,南北绿豆,阿西噶哈,嘻哈亚古"); });
五、练习(计算器)
UI设计:
源码:
#include "caculater.h"
#include "ui_caculater.h"
Caculater::Caculater(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Caculater)
{
ui->setupUi(this);
}
Caculater::~Caculater()
{
delete ui;
}
void Caculater::is_point(QString &str_check)
{
//先做字符串验证 ,末尾不能是小数点
if(str_check.at(str_check.length() - 1) == ".")
{
str_check.append("0");
}
}
void Caculater::result()
{
float res = 0;
switch(op)
{
case DIV:
{
res = left / right;
break;
}
case MUL:
{
res = left * right;
break;
}
case SUB:
{
res = left - right;
break;
}
case ADD:
{
res = left + right;
break;
}
}
QString result = QString::number(res, 'f', 3);
ui->lineEdit_output->setText(result);
ui->lineEdit_input->setText("0");
left = 0;
right = 0;
op = NOT_OP;
QString says;
if(res < 0)
{
says = "等于负";
res = -res;
says.append(QString::number(res,'f',3));
}
else
{
says = "等于";
says.append(result);
}
speaker.say(says);
}
void Caculater::on_btn_num_0_clicked()
{
//判断是否可以输入0
if(ui->lineEdit_input->text() == "0")
{
return;
}
ui->lineEdit_input->insert("0");
speaker.say("0");
}
void Caculater::on_btn_point_clicked()
{
//判断是否可以输入小数点
if(ui->lineEdit_input->text().contains("."))
{
return;
}
ui->lineEdit_input->insert(".");
speaker.say("点");
}
void Caculater::on_btn_num_1_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("1");
speaker.say("1");
return;
}
ui->lineEdit_input->insert("1");
speaker.say("1");
}
void Caculater::on_btn_num_2_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("2");
speaker.say("2");
return;
}
ui->lineEdit_input->insert("2");
speaker.say("2");
}
void Caculater::on_btn_num_3_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("3");
speaker.say("3");
return;
}
ui->lineEdit_input->insert("3");
speaker.say("3");
}
void Caculater::on_btn_num_4_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("4");
speaker.say("4");
return;
}
ui->lineEdit_input->insert("4");
speaker.say("4");
}
void Caculater::on_btn_num_5_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("5");
speaker.say("5");
return;
}
ui->lineEdit_input->insert("5");
speaker.say("5");
}
void Caculater::on_btn_num_6_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("6");
speaker.say("6");
return;
}
ui->lineEdit_input->insert("6");
speaker.say("6");
}
void Caculater::on_btn_num_7_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("7");
speaker.say("7");
return;
}
ui->lineEdit_input->insert("7");
speaker.say("7");
}
void Caculater::on_btn_num_8_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("8");
speaker.say("8");
return;
}
ui->lineEdit_input->insert("8");
speaker.say("8");
}
void Caculater::on_btn_num_9_clicked()
{
if(ui->lineEdit_input->text() == "0")
{
ui->lineEdit_input->setText("9");
speaker.say("9");
return;
}
ui->lineEdit_input->insert("9");
speaker.say("9");
}
//清除
void Caculater::on_btn_CLR_clicked()
{
left = 0;
right = 0;
op = NOT_OP;
ui->lineEdit_input->setText("0");
ui->lineEdit_output->setText("0");
speaker.say("归零");
}
//退格操作
void Caculater::on_btn_BS_clicked()
{
//删除最后一个字符
ui->lineEdit_input->backspace();
//退格后没有字符 做归零处理
if(ui->lineEdit_input->text().length() == 0)
{
ui->lineEdit_input->setText("0");
return;
}
speaker.say("退格");
}
//除法
void Caculater::on_btn_div_clicked()
{
//判断是否已经有运算符
if(op != NOT_OP)
{
return;
}
else
{
op = DIV; //除法运算
}
QString str_check = ui->lineEdit_input->text();
//调用小数点检查
is_point(str_check);
//存入左数
left = str_check.toFloat();
//设置输入栏为0
ui->lineEdit_input->setText("0");
str_check.append("÷");
ui->lineEdit_output->setText(str_check);
speaker.say("除以");
}
void Caculater::on_btn_mul_clicked()
{
//判断是否已经有运算符
if(op != NOT_OP)
{
return;
}
else
{
op = MUL; //除法运算
}
QString str_check = ui->lineEdit_input->text();
//调用小数点检查
is_point(str_check);
//存入左数
left = str_check.toFloat();
//设置输入栏为0
ui->lineEdit_input->setText("0");
str_check.append("×");
ui->lineEdit_output->setText(str_check);
speaker.say("乘以");
}
void Caculater::on_btn_sub_clicked()
{
//判断是否已经有运算符
if(op != NOT_OP)
{
return;
}
else
{
op = SUB; //除法运算
}
QString str_check = ui->lineEdit_input->text();
//调用小数点检查
is_point(str_check);
//存入左数
left = str_check.toFloat();
//设置输入栏为0
ui->lineEdit_input->setText("0");
str_check.append("-");
ui->lineEdit_output->setText(str_check);
speaker.say("减");
}
void Caculater::on_btn_add_clicked()
{
//判断是否已经有运算符
if(op != NOT_OP)
{
return;
}
else
{
op = ADD; //除法运算
}
QString str_check = ui->lineEdit_input->text();
//调用小数点检查
is_point(str_check);
//存入左数
left = str_check.toFloat();
//设置输入栏为0
ui->lineEdit_input->setText("0");
str_check.append("+");
ui->lineEdit_output->setText(str_check);
speaker.say("加");
}
void Caculater::on_btn_equal_clicked()
{
if(op == NOT_OP)
return;
QString str = ui->lineEdit_input->text();
is_point(str);
//右数赋值
right = str.toFloat();
//除法判断除数为0
if(op == DIV && right == 0)
{
ui->lineEdit_output->setText("错误:除数为零");
left = 0;
right = 0;
ui->lineEdit_input->setText("0");
return;
}
//计算结果
result();
}