本文爲視頻教程[1]的筆記。
目錄
一、計算器介紹
1. 界面介紹
包含16個按鈕和一個文本顯示框。
按鈕選擇“Push Button”,顯示屏選擇“LCD Number”。
2. 功能介紹
(1)可對整數進行四則運算,僅能實現2個數之間的運算。例:2+2=4,不能計算2+2+2=6。
(2)按鈕“C”可清除屏幕內容。
(3)出現不合法輸入並按“=”號後,屏幕顯示“-1”。
二、計算器實現
採用類MVC模式實現,Qt安裝參考[2],這裏使用的是5.9.0版本。
新建項目:
選擇創建桌面Qt應用:
項目名稱“exprDemo”:
基類選擇“QDialog”對話框,類名“expr”,勾選“創建界面”:
1. 界面設計(View)
雙擊打開“expr.ui”,設計計算器頁面:
設置畫布大小,選中畫布,在右下角的屬性中設置:
添加顯示屏“LCD Number”和16個按鈕:
效果如下:
對按鈕進行佈局設置,框選所有按鈕,選擇“柵格佈局”:
在右上角全選所有按鈕,修改屬性:
選中整個按鈕組,在畫布中拉取合適的大小,可看到按鈕大小隨着按鈕組大小而同步變化:
選中整個畫布,選擇“垂直佈局”:
在屬性中設置窗口名稱“計算器”:
設置佈局比例“3:7”:
運行程序查看效果:
修改計算器所有按鈕顯示名稱:
修改變量名稱:
所有名稱如下圖所示:
2. 內部方法設計(Model)
實現四則運算的代碼,相關的代碼文件爲“model.h”和“model.cpp”。
右鍵該項目,選擇“添加新文件”:
創建 c++ 文件:
命名爲“model”:
在“model.h”中,定義需使用的方法和變量:
#ifndef MODEL_H
#define MODEL_H
#include <QString>
class model
{
public:
model();
// 方法
void setNum1(int num);
void setNum2(int num);
void setFlag(QString flag);
QString doExpr();
private:
// 定義變量 num1 (+=*/) num2
int num1;
int num2;
QString flag;
};
#endif // MODEL_H
- 計算器實現2個數之間的四則運算,因此定義3個變量,分別保存計算數和運算符。
- 同時定義這3個變量的構造方法,以及運算方法doExpr。
在“model.cpp”中實現這些構造方法的定義:
#include "model.h"
model::model()
{
// 初始化
this->num1 = 0;
this->num2 = 0;
}
// 定義方法,對應model.h中的定義
void model::setNum1(int num)
{
this->num1 = num;
}
void model::setNum2(int num)
{
this->num2 = num;
}
void model::setFlag(QString flag)
{
this->flag = flag;
}
// 當用戶點擊"="號時調用該函數
QString model::doExpr()
{
double result = 0.0;
// switch不能用QStirng,這裏用if
if(this->flag=="+"){
result = this->num1 + this->num2;
}else if(this->flag=="-"){
result = this->num1 - this->num2;
}else if(this->flag=="*"){
result = this->num1 * this->num2;
}else if(this->flag=="/"){
// 除數爲0的情況
if(this->num2==0){
return "-1";
}
result = (this->num1)*1.0 / this->num2;
}else{
// 把int類型轉化成string類型
// 1. str = QString::number(num);
// 2. str = setNum(num);
return QString::number(this->num1);
}
return QString::number(result);
}
因爲輸入只能是整數,因此只有在除法時纔可能出現小數,故除數運算時 *1.0,轉化爲小數。
3. 頁面與內部的交互實現(Control)
整個計算器的大致實現邏輯如下:
(1)在計算器上按順序點擊“數字、符號、數字”,把該數和符號分別獲取並存入num1, flag和num2中。
(2)調用model中的方法進行運算,獲取運算結果result。
(3)將結果result顯示在ui界面的顯示屏上。
該部分相關的代碼文件爲“expr.h”和“expr.cpp”。
在“expr.h”的private中定義,並引入對應頭文件:
#include <QString>
#include "model.h"
...
private:
// 屏幕內容
QString tmp;
// 界面對象和核心功能對象
Ui::expr *ui;
model * mode;
添加槽函數,回到ui界面,右鍵數字“0”按鈕,選擇“轉到槽”:
選擇 點擊 信號:
可以發現“expr.h”和“expr.cpp”中自動添加了對應內容:
對所有按鈕都執行上述操作。
在“expr.cpp”中,新建model,並設置顯示屏的默認值爲0:
expr::expr(QWidget *parent) :
...
{
...
// 新建model,設置顯示屏的默認值爲0
this->mode = new model;
this->tmp = "";
}
tmp存儲的是當前顯示屏上的值,在不進行任何操作時,顯示屏默認顯示0,但tmp值爲空。
對於點擊按鈕實現的效果分別如下:
(1)當按到0-9時
- 在顯示屏上顯示出按下的數字,並且是連在一起的(例:按了1後顯示1,再按2,顯示的是12而不是2)
- 如果第一個數字是0,將不會出現變化(例:按下0000後依然只有0)
對於槽函數0,有:
void expr::on_btn_0_clicked()
{
// 第一個數是0時不會疊加0
if(this->tmp != ""){
// 拼接字符串
this->tmp += this->ui->btn_0->text();
// 把它顯示出來
this->ui->lcd_display->display(this->tmp);
}
}
其中這裏的display(s)方法是把字符串s表示的數字顯示到LCD屏上:
對於槽函數1-9,有:
void expr::on_btn_1_clicked()
{
this->tmp += this->ui->btn_1->text();
this->ui->lcd_display->display(this->tmp);
}
只需修改第一條語句的btn_1爲對應按鈕名即可。
運行效果圖:
(2)當按到四則運算符(+-*/)時
因爲計算器只是實現2個數的運算,因此,在單個式子計算過程中只存在一個運算符,該運算符輸入前屏幕上的數即爲num1。
在該槽函數中,需要存儲num1和flag的值:
void expr::on_btn_plus_clicked()
{
// 用於檢測是否轉化成功
bool ok;
// 1. 把當前屏幕上顯示的string轉爲int存在num中
int num = this->tmp.toInt(&ok);
// 2. 當點擊"+"號時,把num1的值設置爲num
this->mode->setNum1(num);
// 3. 清除當前屏幕
this->tmp = "";
// 4. 記錄點擊的運算符
QString ex = this->ui->btn_plus->text();
this->mode->setFlag(ex);
}
對於 -*/ ,代碼相同,只需把倒數第2行的btn_plus改成對應的按鈕名稱。
(3)當按到 = 符號時
因爲計算器只是實現2個數的運算,因此,在 = 號前屏幕上顯示的數即爲num2。
在該槽函數中,需要存儲num2的值,並根據已有的num1, num2, flag計算出最後的結果result,顯示在屏幕上:
void expr::on_btn_equal_clicked()
{
// 1. 獲取num2
bool ok;
int num = this->tmp.toInt(&ok);
this->mode->setNum2(num);
// 2. 計算num1和num2的運算結果
QString res = this->mode->doExpr();
// 3. 顯示計算結果
this->ui->lcd_display->display(res);
// 4. 清除tmp內容,避免影響後續計算
this->tmp = "";
}
運行效果圖:
(4)當按到清除符號(C)時
功能很簡單,把當前屏幕上的內容置爲0,同時把tmp置爲空。
因爲2個數字和符號反正在下次計算時會重新存儲,即使之前有值也會被覆蓋,所以不用管:
void expr::on_btn_c_clicked()
{
// 清除第一個計算數
this->tmp = "";
// 顯示屏清0
this->ui->lcd_display->display(0);
}
此處display(n)用法:
運行效果圖: