下载地址
http://download.qt.io/archive/qt/
我下载的是 5.12.8 版本的
第四个是windos的
第五个是mac的
第六个是linux的
按需下载就行了
这里有一篇下载安装教程可以看看
https://blog.csdn.net/cfan927/article/details/98115783?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-5&depth_1-utm_source=distribute.pc_releva
(转@Cfan927)
比较详细
b站有个教学视频,可以先看看,他讲的比较详细
https://www.bilibili.com/video/BV1g4411H78N
我个人感觉看到 P10 就行了,因为我知道看我这篇文章的多半都是合工大的孩子被数据结构作业逼疯才来的,先学这么多
弄懂怎么实现按钮的操作,弄懂什么是信号,什么是槽就可以了
有两点可能要注意一下(没有这个大作业的可以不看后面这段)
我们的大作业里面有&& || !三种逻辑运算符
!问题不大
主要是&&和||
这个到时候在计算器输入的时候要输入两个&&
但是我们只入栈一个& 这样方便后面运算
那怎么实现呢?
我们用a来代表你的输入的算式
a[i]遍历这个式子,当 i 指向第一个&时,i++
再入栈运算符,这样就只入栈了一个运算符
|| 和上面的处理方式一样
但是要注意的时 | 的ascii码是 124 ,判断运算符和数字时要注意
其次要注意&& || !之间的优先级,还有运算联系等
else if(a[i]=='&')
{
if(a[i+1]=='&')
i++;
}
类似于上面这样的代码来让它判断
下面放上源码
#include
#include
#include
#include
using namespace std;
int symbol(char c) //赋予优先级
{
switch (c)
{
case '#': return 0;
case '+': return 2;
case '-': return 2;
case '*': return 3;
case '/': return 3;
case '(': return 6;
case ')': return 1;
case '&': return 4;
case '|': return 4;
case '!': return 5;
default: break;
}
return 0;
}
double jisuan( char c='#',double b=1,double a=1)
{
switch (c)
{
case '+': return b + a;
case '-': return b - a;
case '*': return b * a;
case '/': return b / a;
case '&': if(a!=0&&b!=0) return 1;
else return 0;
case '|': if(a==0&&b==0) return 0;
else return 1;
default: break;
}
return 0;
}
double js(double a)
{
if(a==0) return 1;
else return 0;
}
int main()
{
stack<double>s1;
stack<char>s2;
string a;
cout << "请输入" << endl;
cin >> a;
a = a + '#';
s2.push('#');
for (int i = 0;i<a.size(); i++)
{
if (a[i] <= 47||a[i]==124) //用阿斯克码判断扫描到的是数字还是运算符
{
if (a[i] == '#'&&s2.top() == '#') break; //两个#碰到一起运算结束
if (s2.top() == '(') //括号特殊讨论
{
if (a[i] == ')')
{
s2.pop();
continue;
}
s2.push(a[i]);
continue;
}
else if(a[i]=='&')
{
if(a[i+1]=='&')
{
i++;
}
}
else if(a[i]=='|')
{
if(a[i+1]=='|')
{
i++;
}
}
if (symbol(s2.top()) >= symbol(a[i])) //判断运算符优先级
{
if(s2.top()=='!')
{
double vel=js(s1.top());
s1.pop();
s2.pop();
s1.push(vel);
i--;
}
else
{
char temp1 = s2.top();
s2.pop();
double temp2 = s1.top();
s1.pop();
double temp3 = s1.top();
s1.pop();
s1.push(jisuan(temp1, temp3, temp2));
i--;//要把a[i]再走一遍 不然同级运算a[i]不能push
continue;
}
}
else
{
s2.push(a[i]);
continue;
}
}
else //对数字的运算
{
double sum = static_cast<int>(a[i]) - 48;
for (; a[i + 1] > 47&& a[ i + 1 ] != 124 ; i++) //实现多位数的运算
sum = sum * 10 + static_cast<int>(a[i + 1]) - 48;
if(static_cast<int>(a[i+1])==46) //计算小数
{
int j=1;
i=i+2;
for(;a[i]>47&&a[ i ] != 124;i++)
{
sum=sum+pow(10,-j)*(static_cast<int>(a[i]) - 48);
j++;
}
i--;
}
s1.push(sum);
}
}
double result = s1.top();
cout << "计算结果:" << endl;
cout << result ;
}
1. 创立一个widge类型的项目
注意这里把那个Generate form 勾选上,方便后面设计界面
如果没有那就把QT关了 然后点开刚刚创立的路径的文件夹 把那个文件打开
再打开QT
出现如下页面
点击右下方的按钮就好了
如果这还没好,那就说明可能你的QT没有下载完整 有的插件没下
重新下吧
2.开始写代码
2.1 首先我们要想一个问题 如何把计算器按钮上面输入的式子和自己的计算器源码连接起来
我们可以创立一个 QString 类型的字符串 s (QT的头文件一般都是QString,QStack什么的)
每输入一个字符,就把他加入到 s 中
这样最后再把 s 传入你的源码中,进行后面的计算
那他的结果我们也可以用一个QString 类型来记录,我们记为 res
我们再来想一个问题
那个教学视频中也说到过
QT中 widget是一个类,他有头文件,我们想要 s 再每一次按下按钮后都记录
所以我们就可以把 s 定为这个类的私有 ,res 也一样
在widget.h文件中就有这样一段代码
private:
Ui::Widget *ui;
QString s;
QString res;
在widget.cpp文件中的构造函数对它们初始化
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
s=""; //初始化
res=""; //初始化
setWindowTitle("肝到昏天黑地的计算器"); //这是个改变界面名称的函数
}
2.2 我们现在可以来编辑界面了
点开这个文件
我们就进入了设计界面
这是我已经设计好的 注意背景图 (我是男生,这不是我的自拍)
背景图有个链接 讲的也很清楚 https://blog.csdn.net/nb_zsy/article/details/104136793
上面两个白框框 我选择的是 TextEdit,在左边的工具栏能找到
按钮选择的是PUsh button
鼠标选中以后 拖过来就好了
(b站视频按钮是自己输入坐标的,这里的ui直接是自己选位置,方便了很多,这就是在创立新项目时让你们勾选那个Generate form 的原因)
2.3 开始实现按钮
鼠标放到你的按钮上 点击右键
有个 转到槽 的选项
之后选择clicked 这就是点击的信号
点一下之后就跳到了代码页面
之后就在这个函数里面实现你的按钮就可以了
这里我们举一个例子
void Widget::on_pushButton_clicked()
{
s+="1";
ui->textEdit->setText(s);
}
s前面解释过了
ui就是你这个设计页面,textedit就是第一个白框框,setText(s)就是在这个白框框里面输入s
那么这个连起来的意思就是
在你的设计页面中的 textEdi t这个对象中输入 s
具体怎么看对象名,在设计页面,点击你的按钮或者文本框,右上角有显示他的对象名
再说三个特殊的
①后退键 :
void Widget::on_pushButton_20_clicked()
{
s=s.left(s.length()-1);
ui->textEdit->setText(s);
}
②清除键 :
void Widget::on_pushButton_19_clicked()
{
s="";
res="";
ui->textEdit->setText(s);
ui->textEdit_2->setText(res);
}
res是在第二个文本框中的字符串
③ 等号键 :
下面 “= ”的按钮是个特例
我们有两种想法
第一就是直接把你的计算器源码整个放在这个槽函数里面
也可以在外面单独写一个函数,最后return一个值,把这个值传入 = 的槽函数
但是值得注意的有两点
第一
如果你的计算器源码其中一个栈是char类型的,而你的s又是string类型,这样是过不了QT的编译器的
因此要把string转成char型
char *a=s.toLocal8Bit().data();
第二
最后传到设计界面的文本框中的数据应该是Qstring类型
如果你最后的计算结果是 int 或者 double 类型的
要把它转成Qstring的
double num = s1.top();
res = QString::number(num);
ui->textEdit_2->setText(res);
num是我的最后计算结果
textEdit_2是我的第二个文本框的对象名
到现在我们的计算器基本上就完成了
还有两点也要注意一下
第一就是我们在写槽函数的时候 输入文本框的字符一定时英文键盘下的字符,不然程序不会进行的
第二就是QT有的错误不会报错,只会警告,尽量把所有的警告也改了,有的警告不影响结果,有的警告会让最后的程序异常关闭,虽然能编译通过
上面两条都是我血的教训,好几个小时看不出到底是那错了,程序一直异常关闭
我能说的也就这么多了,如果还有什么问题可以发在下面
****有一种营销号的感觉 ****
我的这个计算器的文件在这里
https://gitee.com/jinhesuannaijiaofu/jisuanqi
进去下载那个计算器的文件就好了
下载完成以后用QT打开就OK了
要是看主要部分的代码的话,点开untit 文件里面的widget.cpp文件就行
不用下载就能看