本项目是基于MVC设计模式完成。什么是MVC?
它的全称是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。感兴趣的可以到百度百科具体了解MVC框架,本人也是初学者,只能说说在Qt中用到这种模式时我的理解。V(view)-视图,我们可以理解为Qt中的.ui文件,它是与用户交互的界面;M(model)-模型,通常是我们自己去完成的方法函数,用来处理数据逻辑部分;C(controller)-控制器,就像连接M和V的桥梁,从视图读取数据,控制用户输入,并向模型发送数据。
开发环境:本人使用的是Windows下的Qt5.8.0版本。
先大致预览下完成后的效果:
这个小项目比较适合Qt入门学习,了解布局之后搭建出满意的界面,通过信号与槽机制将界面中的控件与需要实现的功能进行绑定。在功能完善方面有很多需要考虑的地方,本人也遇到了诸多困难。但是,做一个实实在在的东西出来确实是对提高水平很有帮助的,也许你刚开始着手做的时候只是想实现一个简单的功能,但是在项目进行过程中,你也许会发现其实有更好的方法或者有更完美的功能。对你考虑问题的全面性也有很大的帮助。程序猿啊,也许就是在一个又一个的项目旋涡中“享受”吧。
代码部分:
先看我们自己实现的Model部分,可以在Qt中只添加一个类,不需要.ui文件。头文件Model.h
#ifndef MODEL_H
#define MODEL_H
#include <QString>
#include <QtMath>
class Model
{
public:
Model();
void set_num1(double *num); //获取这两个数
void set_num2(double *num);
void set_oper(QString oper); //获取操作符
QString count(); //接口函数,实现加减乘除
QString count1(); //接口函数,实现其他运算
private:
double num1; //定义两个数
double num2;
QString oper; //操作符
};
#endif // MODEL_H
Model.cpp部分
#include "Model.h"
Model::Model() //Model构造函数
{
this->num1 = 0;
this->num2 = 0;
}
void Model::set_num1(double *num)
{
this->num1 = *num;
}
void Model::set_num2(double *num)
{
this->num2 = *num;
}
void Model::set_oper(QString oper)
{
this->oper = oper;
}
//双目运算符:加减乘除
QString Model::count()
{
double result = 0;
if (this->oper.length() > 1)
return "ERROR";
if (this->oper == "+")
{
result = num1 + num2;
}
else if (this->oper == "-")
{
result = num1 - num2;
}
else if (this->oper == "*")
{
result = num1 * num2;
}
else if (this->oper == "÷")
{
if (this->num2 == 0)
return "ERROR"; //这里需要返回字符串,所以返回值是QString型
result = num1 / num2;
}
else
{
return QString::number(this->num1); //将数字转换为QString型
}
return QString::number(result); //将数字转换为QString型
}
//单目运算符:平方、立方、平方根
QString Model::count1()
{
double result = 0;
if (this->oper == "X²")
{
result = this->num1 * this->num1;
}
else if (this->oper == "√")
{
result = qSqrt(this->num1);
}
else if (this->oper == "%")
{
result = this->num1 / 100;
}
else if (this->oper == "sin")
{
result = qSin(this->num1);
}
else if (this->oper == "cos")
{
result = qCos(this->num1);
}
else
{
return QString::number(this->num1);
}
return QString::number(result);
}
然后我们需要一个带界面的界面类,Calculate.h 、Calculate.cpp 和Calculate.ui三个文件,在Calculate.h中,我们可以包含Model.h,这样就可以使用Model类的方法(函数),而主要的算法在Calculate.cpp中,这样做的好处就是可以将视图层和业务层分离,降低耦合性。
Calculate.h文件
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <QDialog>
#include <QString>
#include "Model.h"
namespace Ui {
class Calculator;
}
class Calculator : public QDialog
{
Q_OBJECT
public:
explicit Calculator(QWidget *parent = 0);
~Calculator();
private slots:
void on_btn_0_clicked();
void on_btn_1_clicked();
void on_btn_2_clicked();
void on_btn_3_clicked();
void on_btn_4_clicked();
void on_btn_5_clicked();
void on_btn_6_clicked();
void on_btn_7_clicked();
void on_btn_8_clicked();
void on_btn_9_clicked();
void on_btn_add_clicked();
void on_btn_sub_clicked();
void on_btn_mul_clicked();
void on_btn_div_clicked();
void on_btn_equal_clicked();
void on_btn_clear_clicked();
void on_btn_point_clicked();
void on_btn_squ_clicked();
void on_btn_back_clicked();
void on_btn_root_clicked();
void on_btn_percent_clicked();
void on_btn_sin_clicked();
void on_btn_cos_clicked();
private:
Ui::Calculator *ui;
Model *model;
QString tmp_dis; //获取显示屏le_display中的文本
QString tmp_res; //获取显示屏le_result中的文本
};
#endif // CALCULATOR_H
关于Calculate.cpp也附上源码吧,希望对大家有所帮助
#include "Calculator.h"
#include "ui_Calculator.h"
Calculator::Calculator(QWidget *parent) :
QDialog(parent),
ui(new Ui::Calculator)
{
ui->setupUi(this);
this->model = new Model;
this->tmp_dis = "";
this->tmp_res = "";
}
Calculator::~Calculator()
{
delete ui;
}
//0到9的绑定槽函数
void Calculator::on_btn_0_clicked()
{
bool ok;
double num = this->tmp_res.toDouble(&ok);
if (0 != num || "" == this->tmp_res || 0 != this->tmp_res.contains(".")) //防止在输入0的时候,显示重复的0
{
this->tmp_dis += this->ui->btn_0->text();
this->tmp_res += this->ui->btn_0->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
}
void Calculator::on_btn_1_clicked()
{
this->tmp_dis += this->ui->btn_1->text();
this->tmp_res += this->ui->btn_1->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_2_clicked()
{
this->tmp_dis += this->ui->btn_2->text();
this->tmp_res += this->ui->btn_2->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_3_clicked()
{
this->tmp_dis += this->ui->btn_3->text();
this->tmp_res += this->ui->btn_3->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_4_clicked()
{
this->tmp_dis += this->ui->btn_4->text();
this->tmp_res += this->ui->btn_4->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_5_clicked()
{
this->tmp_dis += this->ui->btn_5->text();
this->tmp_res += this->ui->btn_5->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_6_clicked()
{
this->tmp_dis += this->ui->btn_6->text();
this->tmp_res += this->ui->btn_6->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_7_clicked()
{
this->tmp_dis += this->ui->btn_7->text();
this->tmp_res += this->ui->btn_7->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_8_clicked()
{
this->tmp_dis += this->ui->btn_8->text();
this->tmp_res += this->ui->btn_8->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
void Calculator::on_btn_9_clicked()
{
this->tmp_dis += this->ui->btn_9->text();
this->tmp_res += this->ui->btn_9->text();
this->ui->le_display->setText(this->tmp_dis);
this->ui->le_result->setText(this->tmp_res);
}
//加号被按下时,先获取num1(转化为double型)再获取操作符,操作符给model类
void Calculator::on_btn_add_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num); //这里必须要传指针,不能传值
this->tmp_res = "";
QString opt = this->ui->btn_add->text();
this->model->set_oper(opt);
this->tmp_dis += "+";
this->ui->le_display->setText(this->tmp_dis);
}
//减号被按下时
void Calculator::on_btn_sub_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_sub->text();
this->model->set_oper(opt);
this->tmp_dis += "-";
this->ui->le_display->setText(this->tmp_dis);
}
//乘号被按下时
void Calculator::on_btn_mul_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_mul->text();
this->model->set_oper(opt);
this->tmp_dis += "*";
this->ui->le_display->setText(this->tmp_dis);
}
//除号被按下时
void Calculator::on_btn_div_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_div->text();
this->model->set_oper(opt);
this->tmp_dis += "÷";
this->ui->le_display->setText(this->tmp_dis);
}
//等号被按下时,如果是双目运算符,先获取第二个数num2,再进行相关计算,方法(函数)即为count
void Calculator::on_btn_equal_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num2(&num);
QString ret = this->model->count();
this->ui->le_result->setText(ret);
this->tmp_res = "";
this->tmp_dis = "";
num = 0; //计算结束后将两个数置零
this->model->set_num1(&num);
this->model->set_num2(&num);
}
//平方被按下时,因为不是双目运算符,区别于加减乘除,所以放在另一个接口函数中count1,而且单目运算符操作直接得到结果,不需要再使用等于号
void Calculator::on_btn_squ_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_squ->text();
this->model->set_oper(opt);
this->tmp_dis += "²";
this->ui->le_display->setText(this->tmp_dis);
QString ret = this->model->count1();
this->ui->le_result->setText(ret);
this->tmp_res = "";
}
//开方被按下时
void Calculator::on_btn_root_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_root->text();
this->model->set_oper(opt);
this->tmp_dis = "√" + this->tmp_dis;
this->ui->le_display->setText(this->tmp_dis);
QString ret = this->model->count1();
this->ui->le_result->setText(ret);
this->tmp_res = "";
}
//百分号被按下时
void Calculator::on_btn_percent_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_percent->text();
this->model->set_oper(opt);
this->tmp_dis += "%";
this->ui->le_display->setText(this->tmp_dis);
QString ret = this->model->count1();
this->ui->le_result->setText(ret);
this->tmp_res = "";
}
//sin被按下时
void Calculator::on_btn_sin_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_sin->text();
this->model->set_oper(opt);
this->tmp_dis = "sin" + this->tmp_dis;
this->ui->le_display->setText(this->tmp_dis);
QString ret = this->model->count1();
this->ui->le_result->setText(ret);
this->tmp_res = "";
}
//cos被按下时
void Calculator::on_btn_cos_clicked()
{
double num = this->tmp_res.toDouble();
this->model->set_num1(&num);
this->tmp_res = "";
QString opt = this->ui->btn_cos->text();
this->model->set_oper(opt);
this->tmp_dis = "cos" + this->tmp_dis;
this->ui->le_display->setText(this->tmp_dis);
QString ret = this->model->count1();
this->ui->le_result->setText(ret);
this->tmp_res = "";
}
//清除键按下时,将lineEdit中的文本设置为0,注意,此时,num1仍为上一次运算的num1
void Calculator::on_btn_clear_clicked()
{
this->tmp_res = "";
this->tmp_dis = "";
this->ui->le_display->setText("0");
this->ui->le_result->setText("0");
}
//小数点
void Calculator::on_btn_point_clicked()
{
if (0 == this->tmp_dis.contains(".")) //防止用户输入多个小数点
{
this->tmp_res += this->ui->btn_point->text();
this->tmp_dis += this->ui->btn_point->text();
this->ui->le_result->setText(this->tmp_res);
this->ui->le_display->setText(this->tmp_dis);
}
}
//返回键,即保留文本中左边的length-1位
void Calculator::on_btn_back_clicked()
{
this->tmp_res = this->tmp_res.left(this->tmp_res.length() - 1);
this->ui->le_result->setText(this->tmp_res);
this->tmp_dis = this->tmp_dis.left(this->tmp_dis.length() - 1);
this->ui->le_display->setText(this->tmp_dis);
}
另外再说明一个如何生成.exe文件并添加自己喜欢的图标,可以看起来更像一款软件。
1.找到Qt创建项目时的目录,打开那个目录找到以build-项目名称 开头的文件打开,再打开里面的Debug文件,你要的.exe文件就在这里了,这时你去双击运行会发现少了很多.dll的文件,你需要去你安装Qt路径下(比如博主的路径:X:\Qt\5.8\mingw53_32\bin)找到相应的.dll文件拷贝到Debug文件中。
2.完成了可以双击运行之后,可以右击.exe文件生成一个快捷方式,在右击快捷方式找到属性,如何点击修改图标。这里的图标可以选择系统自带的也可以DIY,方法是选好自己中意的图片,以后,百度搜索“在线制作ico图标”,将自己的图片格式转为ICO格式,最后选择修改即可。
绝招:直接修改应用程序的图标
步骤:
1.创建一个ico后缀的图片。本例Calculator.ico
2.新建一个Calculator.rc的资源文件(名称可以自定义),通过文本编辑器,修改资源文件内容为 IDI_ICON1 ICON DISCARDABLE “Calculator.ico”
3.拷贝Calculator.rc和Calculator.ico到qt的项目中
4.修改pro文件,增加资源文件