Qt基础知识记录(第三篇)

前情提要

        上一篇实现了手搓一个简单的界面,这一篇通过设计功能+信号与槽制作一个满足四则运算的计算器。

即:

                        

创建思路

        先用设计功能画出UI界面,再利用栈的特性存储元素,然后用信号与槽处理逻辑,然后就可以了。

具体步骤

(1)创建项目

项目命名为calculator,并设定为widget,编译模式为qmake

(2)设计UI

打开设计栏,准备用鼠标拖动创建界面

可以看到已经创建了一个长宽都固定为40的按钮

复制出了相同的二十个按钮,然后把它们设成网格布局:先大概把它们排成五行四列,再全部选中选择右上角的网格布局。

再做屏幕上的输出框,使用input 里的lineEdit

然后把按钮改成正确的显示,而不是1

                       

很好,现在UI界面已经差不多了,然后就可以修改按钮的命名了,因为命名现在是1-20,不是很方便

                     

好的,现在用驼峰命名法改成自己想要的名字了

(3)逻辑实现

第一步:先做显示屏部分,思路是开一个字符串,用字符串存储点击的数字和符号

方法:在头文件的私有成员里加上QString类型

                 

这个地方就要实现,点击哪个数哪个数就要出现在显示屏里,需要用到槽了

                             

这个地方点击转到槽,然后在系统自动生成的成员函数里

void Widget::on_oneButton_clicked()
{
    exprecision += "1";
    ui->mainLineEdit->setText(exprecision);
}

写这个,原理就是让字符串多加一个“1”,然后把它增加到ui文件里的mainLineEdit里

现在跑一下代码:

                                 

1可以正常输入,现在我想把窗口名字改一下,可以在构造函数里输入:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("计算器");
}

                                

这个窗口大小不是很美观,我们可以改一下,也是在构造函数里改

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setMaximumSize(210,300);
    this->setMinimumSize(210,300);
    this->setWindowTitle("计算器");
}

宽度设置为210,高度设置为300,差不多的大小,很美观

但是输入框里的字不好看,我们可以再改一下字体:

 QFont f("仿宋",14);
 ui->mainLineEdit->setFont(f);

第一句是创建一个字体对象,第二句是把这个对象设置成输入框的字体

然后就是把0、2-9和+-*/、( )的成员函数全写一遍

好,下面是测试结果:

                                          

接下来再实现clear功能:

void Widget::on_clearButton_clicked()
{
    exprecision.clear();
    ui->mainLineEdit->clear();
}

再实现delete功能:

void Widget::on_deleteButton_clicked()
{
    exprecision.chop(1);
    ui->mainLineEdit->setText(exprecision);
}

测试是动态的,就不放图了。

现在我觉得“=”号按钮的背景颜色不好看,我还想改一下背景颜色,所以我在构造函数里又写了一个改变按钮背景颜色的代码

ui->equalButton->setStyleSheet("background:white");

现在只剩下实现计算逻辑了。

在开篇时已经提到了,用栈存储元素,实现计算。

void Widget::on_equalButton_clicked()
{
    QStack<int> s_num,s_opt;
    char opt[128]={0};
    int i=0,tmp=0,num1,num2;

    //把QString转换成char *
    QByteArray ba;
    ba.append(expression.toUtf8());      //把QString转换成QByteArray
    strcpy(opt,ba.data());

    while(opt[i]!='\0'||s_opt.empty()!=true)
    {
        if(opt[i]>='0'&&opt[i]<='9')
        {
            tmp=tmp*10+opt[i]-'0';
            i++;
            if(opt[i]<'0'||opt[i]>'9')
            {
                s_num.push(tmp);
                tmp=0;
            }
        }
        else                    //操作符
        {
            if(s_opt.empty()==true||Priority(opt[i])>Priority(s_opt.top())||(s_opt.top()=='('&&opt[i]!=')'))
            {
                s_opt.push(opt[i]);
                i++;
                continue;
            }

            if(s_opt.top()=='('&&opt[i]==')')
            {
                s_opt.pop();
                i++;
                continue;
            }

            if(Priority(opt[i])<=Priority(s_opt.top())||(opt[i]==')'&&s_opt.top()!='(')||(opt[i]=='\0'&&s_opt.empty()!=true))
            {
                char ch=s_opt.top();
                s_opt.pop();
                switch(ch)
                {
                    case '+':
                        num1=s_num.top();
                        s_num.pop();
                        num2=s_num.top();
                        s_num.pop();
                        s_num.push(num1+num2);
                        break;
                    case '-':
                        num1=s_num.top();
                        s_num.pop();
                        num2=s_num.top();
                        s_num.pop();
                        s_num.push(num1-num2);
                        break;
                    case '*':
                        num1=s_num.top();
                        s_num.pop();
                        num2=s_num.top();
                        s_num.pop();
                        s_num.push(num1*num2);
                        break;
                    case '/':
                        num1=s_num.top();
                        s_num.pop();
                        num2=s_num.top();
                        s_num.pop();
                        s_num.push(num1/num2);
                        break;
                }
            }
        }
    }
    ui->mainLineEdit->setText(QString::number(s_num.top()));
    expression.clear();
}
int Widget::Priority(char ch)
{
    switch(ch)
    {
    case '(':
        return 3;
    case '*':
    case '/':
        return 2;
    case '+':
    case '-':
        return 1;
    default:
        return 0;
    }
}

利用这段代码最后就可以实现一个简陋的计算器。

篇末总结

这项工程主要包括:ui的拖动及控件名的修改,按钮点击后在输入框的显示,等于号点击后的计算逻辑。

ui拖动和按钮显示比较好实现,核心点在于通过一个QString类的expression增删改,然后重新输出在输入框中。

计算逻辑要用到栈将数字和符号拆开处理,利用栈的特性将数据存储起来。

这个项目的收获:

1. 知道了Qt如何创建ui界面

2. 知道了设计栏的属性工具栏部分属性的作用

3. 知道Qt的面向对象非常重要,库函数都是利用面向对象实现的

4. 知道了一些库函数的用法,明白了Qt的基本使用逻辑,即利用Qt提供的库函数完成对界面的修改,对逻辑的实现,语法都是面向对象

5. 更深入地理解了槽,知道槽是一个函数,是在按钮类触发某个条件后要进行的动作。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值