刚开始学习QT,发现QT真的是一个功能很强大的开发软件,所以用QT做了一个简单的计算器来熟悉一下QT。
1.首先,先建立一个QT项目的工程文件:如下
项目保存位置和项目文件名字自己选择,最好是每个项目单独一个文件夹,便于保存和分享。
上面显示的是在安装QT时自己选者安装的环境,有很多,看自己的需求,对号入座就行。
基类选择QWidget或者QMainWidget都可以,如果需要用QT的ui布局设置窗口就需要勾选创建界面,如果需要纯代码创建界面就不用勾选(两者最好不要 一起用)。
点击完成即可。
想要检查软件环境安装好没有,可以点击运行,如果出现一个白板界面,则说明创建项目成功,同时软件环境也是没有问题的。
接下来就是需要开始对计算机的界面进行简单的设计,初学QT的话一般是先使用ui来进行界面的设计,通过对功能块的拖曳来达到界面实现的一个效果,后面了解的稍微深入一点之后,可以逐渐的改为纯代码设计界面。
首先进入ui编辑界面:
点进去之后在左边菜单栏会有很多的功能选项,主要包括界面会用到的一些按钮,按键,文档窗口,功能按钮等;
这些功能块都是用英文标识的,如果英语基础较好阅读起来还是比较方便,但其实多用几次其实也就熟悉了,没什么难的,也没必要花时间去记忆这些单词,这些功能块都是分好的区的,不需要这一块功能的时候也是可以把他收起来。
好了,现在正文 开启,制作一个计算器界面:
首先,先框选一个大概的区域,用于摆放功能块:
规划好自己准备设计的计算器的大小,大概框选出一个用来放功能块的区域,然后想一下计算器应该怎么来设计,可以参考我们电脑自带的一个计算器来进行设计。
这是电脑自带的一个计算器的,就按它这个功能来进行设计,当然,初次设计的功能可能没有电脑上的那么齐全,本次设计的目标是能实现基本的加减乘除功能。
好了,布局开始:
1.首先,需要按钮,悬着Bottons区域的Pushbotton功能块;
根据大概的所需按键数量,先选择了15个按钮,不用一个一个的拖出来,可以先排列好之后,一行一行的粘贴复制,只是这样可能会造成他的标号乱序,在后面进行槽函数连接的时候需要注意一下。
然后后点击按钮并单击鼠标右键,点击改变文本,编辑按钮的名字,就按计算器的样式编辑即可:
如图,简单的计算器样式已经出来了,当然,功能肯定是还不齐全的,这只是基本的按钮模块。。。
好了,现在需要添加的就是显示模块了,显示部分添加的器件一般都是添加的LineEdit 和TextEdit两种,一个可以用来显示实时输入的数据,一个用来显示历史输入的数据。
现在已经将计算器的控件已经添加好了,可以先简单的布局一下,让界面稍微美观一点。
可以框选上面的所有控件点击布局方式来进行布局,也可以自己手动拖动来布局。这里不做过多介绍。
做完这些之后可以点击运行看一下效果,可以看到一个计算器的基本模型已经出来了。
但是现在点击按键按下说不会有任何反应的,这是因为还没有添加信号和槽,等到信号和槽添加上之后,按下按键就能在显示框内看到想要的数据。
那么要如何来添加信号与槽呢?ui界面添加还是比较方便快捷的,选中界面上的控件,点击右键转到槽或者下方的空白框下面有个绿色的加号哪里,这样转到槽之后她会自动帮你生成槽函数的定义和框架,但是并不推荐这一种方法,比较好用的办法就是直接到widget.cpp里面进行。
进行信号和槽的连接,用的时connect()进行连接,这里面的参数如何设置,可以在QT左边的帮助里面点击查询,输入connect之后会出现该函数的使用方法和参数意义,包括后面会用到的一些其他功能都是可以在这里进行查询,这些要全部熟练掌握是不可能的,这些都是边学边记。所以这里不做过多阐述。
//connect 信号和槽的连接
connect(ui->pushButton_1,SIGNAL(clicked(bool)),this,SLOT(number_clicked));
/*
*ui->pushButton_1 :ui界面下设计的控件对象名称
*SINGNAL(clicked(bool)): 触发信号,clicked(bool)点击事件
*this :表示在这个界面上
*SLOT(num_clicked):当有点击当前对象触发槽,执行槽函数,num_ckicked()用户自定义槽函数,根据自身需求来定义
因为一共有是个数字键,所以要建立十个信号和槽的连接。
connect(ui->pushButton_1,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_2,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_3,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_4,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_5,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_6,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_7,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_8,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_9,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
connect(ui->pushButton_10,SIGNAL(clicked(bool)),this,SLOT(number_clicked()));
这样我们已经建立好是个数字按键的槽连接了,接下来开始写槽函数。
槽函数的功能当然是读取按键的键值,然后将键值显示在显示框内。槽函数要定义,而且只能定义在private slots:下
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void number_clicked();//自定义槽函数
private:
Ui::Widget *ui;
};
槽函数number_clicked()
void Widget::number_clicked(){
//找到信号的发送者 dynamic_cast标准转换函数,如果强转会出现问题
QPushButton *num = dynamic_cast <QPushButton *>(sender());
ui->lineEdit->setText(num->text());
}
/*sender()返回发送信号的对象的指针,其实就是判断是那个对象触发了槽函数,
定位到当前按钮,因为在按钮中多个对象对应一个槽函数*/
现在当我们点击按钮就可以看到窗口上显示当前按键对应的值,但是当点击另外一个按钮或者重复点击的时候,当前值就会覆盖掉原来的值,所以这里要进行处理。
void Widget::number_clicked(){
//找到信号的发送者 dynamic_cast标准转换函数,如果强转会出现问题
QPushButton *num = dynamic_cast <QPushButton *>(sender());
QString str = ui->pushButton->text(); //设置一个str回去文本框内容,和输入的内容放一起即可;
ui->lineEdit->setText(str+num->text());
}
好了,现在已经实现了内容的输入,接下来要做的就是如何提取输入框内的字符进行运算。
提取输入框内容之前应该先要一个信号来触发这个提取的指令,这里单独写一个槽函数来管理这些指令,以等于符号位标志,如果单击了这个按钮,就提取文本框内的内容进行运算。
在原来的界面上加了一个lcd控件来显示结果,小数点以及清除退格键,split()用来分隔提取出来的字符,以什么为基准点分割就在括号中填入什么。toInt()用来把数据转换为int型。
当然,也是需要判断是否输入了运算符,检测到不同的运算符就进行不同的方式进行运算,最后将结果显示出来。同时,设立一个标志位,检测是否有小数点的输入。
void MainWindow::eq_clicked(){
//提取编辑框中的表达式
QString str = ui->lineEdit->text();
QList <QString> list;
if(bit == 0){
if(flag=="+"){
list = str.split("+");
sum = list.at(0).toInt()+list.at(1).toInt();
ui->lcdNumber->display(sum);
QString s = QString::number(sum);
ui->lineEdit->setText(s);
ui->textEdit->append(str+"="+s);
//append()用于追加内容
}
else if(flag=="-"){
list = str.split("-");
sum = list.at(0).toInt()-list.at(1).toInt();
ui->lcdNumber->display(sum);
QString s = QString::number(sum);
ui->lineEdit->setText(s);
ui->textEdit->append(str+"="+s);
}
else if(flag=="*"){
list = str.split("*");
sum = list.at(0).toInt()*list.at(1).toInt();
ui->lcdNumber->display(sum);
QString s = QString::number(sum);
ui->lineEdit->setText(s);
ui->textEdit->append(str+"="+s);
}
else if(flag=="/"){
list = str.split("/");
double sum1 = list.at(0).toDouble()/list.at(1).toDouble();
ui->lcdNumber->display(sum1);
QString s = QString::number(sum1);
ui->lineEdit->setText(s);
ui->textEdit->append(str+"="+s);
}
}
//有double型数据
if(bit == 1){
double sum1;
if(flag=="+"){
list = str.split("+");
sum1 = list.at(0).toDouble()+list.at(1).toDouble();
ui->lcdNumber->display(sum1);
}
else if(flag=="-"){
list = str.split("-");
sum1 = list.at(0).toDouble()-list.at(1).toDouble();
ui->lcdNumber->display(sum1);
}
else if(flag=="*"){
list = str.split("*");
sum1 = list.at(0).toDouble()*list.at(1).toDouble();
ui->lcdNumber->display(sum1);
}
else if(flag=="/"){
list = str.split("/");
sum1 = list.at(0).toDouble()/list.at(1).toDouble();
ui->lcdNumber->display(sum1);
}
QString s = QString::number(sum1);
ui->lineEdit->setText(s);
ui->textEdit->append(str+"="+s);
}
//分解操作数与运算符,以列表的形式存储操作数
// QList list = str.split("+");
//计算
//sum = list.at(0).toInt()+list.at(1).toInt();//+
//ui->lcdNumber->display(sum);
// ui->lineEdit->setText(sum);
//int 转 String
//QString s = QString::number(sum);
//ui->lineEdit->setText(s);
//输出到历史记录框中
//ui->textEdit->append(str+"="+s);
}
这里篇幅有点过大,前面太啰嗦了,后面也没有什么重要的点了,清空用clear()就可以了,退格就是chop(),比如,
str.chop(1);//退格,使用chop()去除str字符串最右边n个字符
因为这个界面是用ui做的,代码放上来,界面设置的对象名不一样,也是没法用的,所以后面就不贴代码了,后面会作一个纯代码的界面,并且尽可能将计算器的功能完善,目前这个计算器的问题很多,当个借鉴就好,很多问题可以自己尝试修改。