wxWidgets学习笔记(四):编写一个简易的计算器程序

一、开发环境

  • 操作系统:Fedora 23
  • 集成开发环境:Code::Blocks 16.01
  • G++版本:5.3.1
  • GTK+版本:2.24.30(使用命令sudo dnf install gtk2 gtk2-devel gtk2-devel-docs安装)
  • wxWidgets版本:3.1.0(解压源码包后进入顶层目录依次输入./configuremakesudo make install三条命令)

二、程序设计思路

设计一个Calculator类包含用于显示和编辑文本的文本框,和表示数字、运算符、清零和关闭窗口的按钮,以及用于保存临时数据的变量和事件处理函数。

在Calculator类的构造函数内初始化成员变量以及成员对象,并且布局好文本框和各个按钮。

由数字按钮的点击事件的事件处理函数或者直接用键盘将数字输入文本框。

由加减乘除按钮的点击事件的事件处理函数将文本框内的数字保存到用于保存第一个运算值的Calculator类的成员变量内,并且将运算方式保存到用于保存运算方式的Calculator类的成员变量内。

由等号按钮点击事件的事件处理函数将文本框内的数字保存到用于保存第二个运算值的Calculator类的成员变量内,函数根据保存运算方式的Calculator类的成员变量的值进行运算,运算后将结果输出到文本框。

进行平方运算和开方运算的按钮的事件处理函数将把文本框内的数字直接运算后输出到文本框。

点击清除按钮将清除Calculator类中的数据,点击关闭按钮将关闭程序。

如果输入的数据不合法,则数据将被清零。

三、编写并解读源代码

了解有关wxWidgets框架的基本知识请阅读: wxWidgets学习笔记(一):解读Code::Blocks模板工程源代码
1、新建一个名为CalculatorApp.h的头文件,在头文件中定义一个名为MyApp的wxApp派生类:

#ifndef CALCULATORAPP_H
#define CALCULATORAPP_H

#include 

class MyApp : public wxApp
{
    public:
        virtual bool OnInit();
};

#endif // CALCULATORAPP_H

2、新建一个名为CalculatorApp.cpp的C++源代码文件,在源代码文件中定义MyApp类的OnInit成员函数。该成员函数新建了一个Calculator类的calculator对象(Calculator类将在下一步中定义),并且向Calculator类的构造函数传递了一个内容为“Calculator”的wxString类型的参数。然后调用calculator->Show(true);将窗口显示出来:

#include "CalculatorApp.h"
#include "CalculatorMain.h"

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
     Calculator* calculator = new Calculator(wxT("Calculator"));

     calculator->Show(true);

     return true;
}

3、新建一个名为CalculatorMain.h的头文件,在头文件中定义一个名为Calculator的wxFrame派生类。该Calculator类包含用于显示和编辑文本的文本框和各个按钮的对象,以及用于保存和运算数据的变量、对象和函数,还有各个按钮的ID和事件处理函数:

#ifndef CALCULATORMAIN_H
#define CALCULATORMAIN_H

#include 
#include "CalculatorApp.h"

class Calculator : public wxFrame
{
    public:
        /*定义各个按钮的ID*/
        enum
        {
            ID_CLS = 101,
            ID_BAC,
            ID_ZERO,
            ID_ONE,
            ID_TWO,
            ID_THREE,
            ID_FOUR,
            ID_FIVE,
            ID_SIX,
            ID_SEVEN,
            ID_EIGHT,
            ID_NINE,
            ID_PLUS,
            ID_MINUS,
            ID_DIVIDE,
            ID_RIDE,
            ID_POINT,
            ID_EQUAL,
            ID_PF,
            ID_KF
        };

        /*定义五个用于运算的成员变量和成员对象*/
        double m_value1;    //定义用于保存第一个运算值的成员变量
        double m_value2;    //定义用于保存第二个运算值的成员变量
        double result;      //定义用于保存运算结果的成员变量
        int c_sign;         //定义用于保存运算方式的成员变量,0代表加,1代表减,2代表乘以,3代表除以
        wxString m_str;     //定义用于临时保存并处理字符串以及浮点类型数据的成员对象

        /*定义一个用于显示和编辑文本的文本框成员对象*/
        wxTextCtrl* tc1;

        /*定义各个按钮的成员对象*/
        wxButton* btcls;
        wxButton* btbac;
        wxButton* btclose;
        wxButton* bt1;
        wxButton* bt2;
        wxButton* bt3;
        wxButton* bt4;
        wxButton* bt5;
        wxButton* bt6;
        wxButton* bt7;
        wxButton* bt8;
        wxButton* bt9;
        wxButton* bt0;
        wxButton* btplus;
        wxButton* btminus;
        wxButton* btdivide;
        wxButton* btride;
        wxButton* btpoint;
        wxButton* btequal;
        wxButton* pingfang;
        wxButton* kaifang;

        /*声明构造函数*/
        Calculator(const wxString& title);

        /*声明两个将要被事件处理函数调用的函数*/
        //将文本框内的字符串转换为Double类型的值存入m_value1,并且清空文本框
        void SaveVale1();
        //将文本框内的字符串转换为Double类型的值存入m_value2,
        //然后根据c_sign保存的运算方式对im_value1和m_value2进行运算,
        //最后将运算结果转换为字符串输出至文本框。
        void Calculate();

        /*声明各个按钮的事件处理函数*/
        void OnBt0(wxCommandEvent& event);  //按钮“0”的事件处理函数,将数字0输出到文本框
        void OnBt1(wxCommandEvent& event);  //按钮“1”的事件处理函数,将数字1输出到文本框
        void OnBt2(wxCommandEvent& event);  //按钮“2”的事件处理函数,将数字2输出到文本框
        void OnBt3(wxCommandEvent& event);  //按钮“3”的事件处理函数,将数字3输出到文本框
        void OnBt4(wxCommandEvent& event);  //按钮“4”的事件处理函数,将数字4输出到文本框
        void OnBt5(wxCommandEvent& event);  //按钮“5”的事件处理函数,将数字5输出到文本框
        void OnBt6(wxCommandEvent& event);  //按钮“6”的事件处理函数,将数字6输出到文本框
        void OnBt7(wxCommandEvent& event);  //按钮“7”的事件处理函数,将数字7输出到文本框
        void OnBt8(wxCommandEvent& event);  //按钮“8”的事件处理函数,将数字8输出到文本框
        void OnBt9(wxCommandEvent& event);  //按钮“9”的事件处理函数,将数字9输出到文本框
        //按钮“,”的事件处理函数,将小数点输出到文本框
        void OnBtPoint(wxCommandEvent& event);
        //按钮“=”的事件处理函数,调用Calculate函数计算并显示结果
        void OnBtEqual(wxCommandEvent& event);
        //按钮“Cls”的事件处理函数,清零m_value1和m_value2两个运算值,清空m_str对象中的数据
        void OnBtCls(wxCommandEvent& event);
        //按钮“Close”的事件处理函数,关闭程序
        void OnBtClose(wxCommandEvent& event);
        //按钮“+”的事件处理函数,调用SaveVale1函数将文本框内的数据存入第一个运算值m_value1并且清空文本框,然后将c_sign赋值为0,表示进行加运算
        void OnPlus(wxCommandEvent& event);
        //按钮“-”的事件处理函数,调用SaveVale1函数将文本框内的数据存入第一个运算值m_value1并且清空文本框,然后将c_sign赋值为1,表示进行减运算
        void OnMinus(wxCommandEvent& event);
        //按钮“*”的事件处理函数,调用SaveVale1函数将文本框内的数据存入第一个运算值m_value1并且清空文本框,然后将c_sign赋值为2,表示进行乘以运算
        void OnDivide(wxCommandEvent& event);
        //按钮“/”的事件处理函数,调用SaveVale1函数将文本框内的数据存入第一个运算值m_value1并且清空文本框,然后将c_sign赋值为3,表示进行除以运算
        void OnRide(wxCommandEvent& event);
        //按钮“pf”的事件处理函数,将文本框内的字符串转换为Double类型的值,平方后转化为字符串类型清空文本框并输出
        void OnPF(wxCommandEvent& event);
        //按钮“kf”的事件处理函数,将文本框内的字符串转换为Double类型的值,开根后转化为字符串类型清空文本框并输出
        void OnKF(wxCommandEvent& event);
};

#endif // CALCULATORMAIN_H

4、新建一个名为CalculatorMain.cpp的C++源代码文件,在源代码文件中定义Calculator类的构造函数和其他成员函数。在构造函数内初始化了各个用于运算的成员变量和成员对象,还初始化了文本框和各个按钮,并且设置了类对象中文本框和各个按钮的布局:

#include <math.h>
#include "CalculatorMain.h"

Calculator::Calculator(const wxString& title)
           :wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxSize(270,350))
{
    /*初始化各个用于运算的成员变量和成员对象*/
    m_value1 = 0;
    m_value2 = 0;
    result= 0;
    c_sign = 0;
    m_str = "";

    /*新建一个名为vbox的垂直排列的wxBoxSizer对象,用于布局文本框和各个按钮*/
    wxBoxSizer* vbox = new wxBoxSizer(wxVERTICAL);

    /*初始化tc1文本框对象,并且将tc1文本框添加到名为vbox的wxBoxSizer中*/
    //构造函数参数的意义依次为:无父窗口类,默认的控制ID,空的默认文本,默认位置,默认大小,文本左对齐
    tc1 = new wxTextCtrl(this, -1, wxT(""), wxPoint(-1, -1),
        wxSize(-1, -1), wxTE_LEFT);
    //Add函数参数的意义依次为:添加到vbox中的窗口类为tc1类,
    //文本框的垂直大小不会随着垂直排列的wxBoxSizer的垂直变化而变化,
    //将文本框填充整个区域|顶端对齐|低端对齐,
    //定义边界宽度为4像素.
    vbox->Add(tc1,0,wxEXPAND | wxBOTTOM | wxTOP ,4);

    /*初始化按钮,指定每个按钮的ID和显示的内容,第一个参数的意思是没有父类*/
    btcls = new wxButton(this,ID_CLS,wxT("Cls"));
    btclose = new wxButton(this,wxID_EXIT,wxT("Close"));
    bt1 = new wxButton(this,ID_ONE,wxT("1"));
    bt2 = new wxButton(this,ID_TWO,wxT("2"));
    bt3 = new wxButton(this,ID_THREE,wxT("3"));
    bt4 = new wxButton(this,ID_FOUR,wxT("4"));
    bt5 = new wxButton(this,ID_FIVE,wxT("5"));
    bt6 = new wxButton(this,ID_SIX,wxT("6"));
    bt7 = new wxButton(this,ID_SEVEN,wxT("7"));
    bt8 = new wxButton(this,ID_EIGHT,wxT("8"));
    bt9 = new wxButton(this,ID_NINE,wxT("9"));
    bt0 = new wxButton(this,ID_ZERO,wxT("0"));
    btpoint = new wxButton(this,ID_POINT,wxT("."));
    btplus = new wxButton(this,ID_PLUS,wxT("+"));
    btminus = new wxButton(this,ID_MINUS,wxT("-"));
    btride = new wxButton(this,ID_RIDE,wxT("*"));
    btdivide = new wxButton(this,ID_DIVIDE,wxT("/"));
    btequal = new wxButton(this,ID_EQUAL,wxT("="));
    pingfang = new wxButton(this,ID_PF,wxT("pf"));
    kaifang = new wxButton(this,ID_KF,wxT("kf"));

    /*定义一个名为gs的GridSizer,并且向gs中添加各个按钮,最后将gs添加进vbox*/
    //构造函数参数的意义依次为:5行组件,4列组件,纵向组件间距离为4像素,横向组件间距离为4像素
    wxGridSizer* gs = new wxGridSizer(5,4,4,4);
    //Add函数参数的意义依次为:添加到gs中的窗口类为btcls类,
    //第二个参数仅仅对于wxBoxSizer类中的Add函数有效,
    //将按钮填充整个区域。
    gs->Add(btcls,0,wxEXPAND);
    gs->Add(btclose,0,wxEXPAND);
    gs->Add(pingfang,0,wxEXPAND);
    gs->Add(kaifang,0,wxEXPAND);
    gs->Add(bt7,0,wxEXPAND);
    gs->Add(bt8,0,wxEXPAND);
    gs->Add(bt9,0,wxEXPAND);
    gs->Add(btdivide,0,wxEXPAND);
    gs->Add(bt4,0,wxEXPAND);
    gs->Add(bt5,0,wxEXPAND);
    gs->Add(bt6,0,wxEXPAND);
    gs->Add(btride,0,wxEXPAND);
    gs->Add(bt1,0,wxEXPAND);
    gs->Add(bt2,0,wxEXPAND);
    gs->Add(bt3,0,wxEXPAND);
    gs->Add(btminus,0,wxEXPAND);
    gs->Add(bt0,0,wxEXPAND);
    gs->Add(btpoint,0,wxEXPAND);
    gs->Add(btequal,0,wxEXPAND);
    gs->Add(btplus,0,wxEXPAND);
    //Add函数参数的意义依次为:添加到vbox中的窗口类为gs类,
    //gs的垂直大小会随着垂直排列的wxBoxSizer的垂直变化而变化,
    //将按钮填充整个区域。
    vbox->Add(gs,1,wxEXPAND);

    /*绑定按钮、事件和事件处理函数*/
    Connect(ID_CLS,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBtCls));
    Connect(wxID_EXIT,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBtClose));
    Connect(ID_SEVEN,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt7));
    Connect(ID_EIGHT,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt8));
    Connect(ID_NINE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt9));
    Connect(ID_DIVIDE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnDivide));
    Connect(ID_FOUR,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt4));
    Connect(ID_FIVE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt5));
    Connect(ID_SIX,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt6));
    Connect(ID_RIDE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnRide));
    Connect(ID_ONE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt1));
    Connect(ID_TWO,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt2));
    Connect(ID_THREE,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt3));
    Connect(ID_MINUS,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnMinus));
    Connect(ID_ZERO,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBt0));
    Connect(ID_POINT,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBtPoint));
    Connect(ID_EQUAL,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnBtEqual));
    Connect(ID_PLUS,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnPlus));
    Connect(ID_PF,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnPF));
    Connect(ID_KF,wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler(Calculator::OnKF));

    SetSizer(vbox);//将vbox的布局设置为Calculator窗口类对象的布局
    SetMinSize(wxSize(270,220));//设置窗口的最小宽度为270像素,最小高度为220像素
    Centre();
}

void Calculator::OnBt0(wxCommandEvent& event)
{
    wxString num0 = _T("0");
    tc1->WriteText(num0);
}

void Calculator::OnBt1(wxCommandEvent& event)
{
    wxString num1 = _T("1");
    tc1->WriteText(num1);
}

void Calculator::OnBt2(wxCommandEvent& event)
{
    wxString num2 = _T("2");
    tc1->WriteText(num2);
}

void Calculator::OnBt3(wxCommandEvent& event)
{
    wxString num3 = _T("3");
    tc1->WriteText(num3);
}

void Calculator::OnBt4(wxCommandEvent& event)
{
    wxString num4 = _T("4");
    tc1->WriteText(num4);
}

void Calculator::OnBt5(wxCommandEvent& event)
{
    wxString num5 = _T("5");
    tc1->WriteText(num5);
}

void Calculator::OnBt6(wxCommandEvent& event)
{
    wxString num6 = _T("6");
    tc1->WriteText(num6);
}

void Calculator::OnBt7(wxCommandEvent& event)
{
    wxString num7 = _T("7");
    tc1->WriteText(num7);
}

void Calculator::OnBt8(wxCommandEvent& event)
{
    wxString num8 = _T("8");
    tc1->WriteText(num8);
}

void Calculator::OnBt9(wxCommandEvent& event)
{
    wxString num9 = _T("9");
    tc1->WriteText(num9);
}

void Calculator::OnBtPoint(wxCommandEvent& event)
{
    wxString point = _T(".");
    tc1->WriteText(point);
}

void Calculator::OnBtCls(wxCommandEvent& event)
{
    tc1->Clear();//清除文本框内容
    m_str = "";
    m_value1 = 0;
    m_value2 = 0;
}

void Calculator::OnBtClose(wxCommandEvent& event)
{
    Close();
}

void Calculator::SaveVale1()//保存第一次输入数字
{
    m_str = tc1->GetValue();
    m_str.ToDouble(&m_value1);//把字符转化为double类型
    tc1->Clear();
}

void Calculator::OnPlus(wxCommandEvent& event)
{
    SaveVale1();
    c_sign = 0;
}

void Calculator::OnMinus(wxCommandEvent& event)
{
    SaveVale1();
    c_sign = 1;
}

void Calculator::OnRide(wxCommandEvent& event)
{
    SaveVale1();
    c_sign = 2;
}

void Calculator::OnDivide(wxCommandEvent& event)
{
    SaveVale1();
    c_sign = 3;
}

void Calculator::OnPF(wxCommandEvent& event)
{
    wxString str;//用来输出最终结果
    double a1;//用来保存最终结果
    m_str=tc1->GetValue();
    m_str.ToDouble(&m_value1);
    a1 = m_value1*m_value1;
    str<<a1;
    tc1->Clear();
    tc1->WriteText(str);
}

void Calculator::OnKF(wxCommandEvent& event)
{
    wxString str;
    double a1;
    m_str=tc1->GetValue();
    m_str.ToDouble(&m_value1);
    a1 = sqrt(m_value1);
    str<<a1;
    tc1->Clear();
    tc1->WriteText(str);
}

void Calculator::Calculate()
{
    wxString str;//输出最终结果
    m_str = tc1->GetValue();
    m_str.ToDouble(&m_value2);

    switch(c_sign)
    {
        case 0:
        {
            result = m_value1 + m_value2;
            break;
        }
        case 1:
        {
            result = m_value1 - m_value2;
            break;
        }
        case 2:
        {
            result = m_value1 * m_value2;
            break;
        }
        case 3:
        {
            result = m_value1 / m_value2;
            break;
        }
    }

    str<<result;//把结果转化为字符
    tc1->Clear();
    tc1->WriteText(str);
}

void Calculator::OnBtEqual(wxCommandEvent& event)
{
    Calculate();
}

5、编译并运行:
wxWidgets学习笔记(四):编写一个简易的计算器程序_第1张图片

你可能感兴趣的:(wxWidgets)