Qt學習(5)——寫一下簡單的計算器
阿新 • • 發佈:2018-12-10
可以執行+-*/浮點運算,直接上程式碼了
訊號和槽的簡單運用;
思路:先將字串轉化成浮點數和符號;再將中綴表示式轉化為逆波蘭式;最後直接計算。
Calculate.pro
#------------------------------------------------- # # Project created by QtCreator 2018-09-15T16:53:19 # #------------------------------------------------- QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Calculator TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.h \ floatnumber.h CONFIG += C++11
Headers:
floatnumber.h
#ifndef FLOATNUMBER_H
#define FLOATNUMBER_H
#endif // FLOATNUMBER_H
#include <iostream>
using namespace std;
struct node{
int flag;
union{
double a; //flag==0
char op; //flag==1
}num;
};
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QStack> #include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); void calculate(); int process(char a, char b); private: QString s; //QStack<double> num; //stack<char> operation; }; #endif // MAINWINDOW_H
Sources:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindows.cpp
#include "mainwindow.h" #include <QPushButton> #include <QStack> #include <QTextEdit> #include <QDebug> #include "floatnumber.h" typedef struct node _tNode; #define NUM_OF_NUMBER 20 #define KIND_NUMBER 0 #define KIND_OPERATOR 1 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { //初始化 s = ""; resize(510,510); setWindowTitle("計算器"); //設定按鈕,指定父物件 QPushButton *button_1 = new QPushButton(this); QPushButton *button_2 = new QPushButton(this); QPushButton *button_3 = new QPushButton(this); QPushButton *button_4 = new QPushButton(this); QPushButton *button_5 = new QPushButton(this); QPushButton *button_6 = new QPushButton(this); QPushButton *button_7 = new QPushButton(this); QPushButton *button_8 = new QPushButton(this); QPushButton *button_9 = new QPushButton(this); QPushButton *button_0 = new QPushButton(this); QPushButton *button_add = new QPushButton(this); QPushButton *button_dec = new QPushButton(this); QPushButton *button_mul = new QPushButton(this); QPushButton *button_div = new QPushButton(this); QPushButton *button_clear = new QPushButton(this); QPushButton *button_equal = new QPushButton(this); QPushButton *button_point = new QPushButton(this); QPushButton *button_left = new QPushButton(this); QPushButton *button_right = new QPushButton(this); QPushButton *button_delete = new QPushButton(this); button_0->setText("0"); button_1->setText("1"); button_2->setText("2"); button_3->setText("3"); button_4->setText("4"); button_5->setText("5"); button_6->setText("6"); button_7->setText("7"); button_8->setText("8"); button_9->setText("9"); button_add->setText("+"); button_dec->setText("-"); button_mul->setText("*"); button_div->setText("/"); button_clear->setText("CE"); button_equal->setText("="); button_point->setText("."); button_left->setText("("); button_right->setText(")"); button_delete->setText("Del"); //設定顯示視窗 QTextEdit *text = new QTextEdit(this); text->resize(490,90); text->move(10,10); //佈局 button_0->resize(90,90); button_0->move(10,110); button_1->resize(90,90); button_1->move(110,110); button_2->resize(90,90); button_2->move(210,110); button_3->resize(90,90); button_3->move(310,110); button_4->resize(90,90); button_4->move(10,210); button_5->resize(90,90); button_5->move(110,210); button_6->resize(90,90); button_6->move(210,210); button_7->resize(90,90); button_7->move(310,210); button_8->resize(90,90); button_8->move(10,310); button_9->resize(90,90); button_9->move(110,310); button_add->resize(90,90); button_add->move(210,310); button_dec->resize(90,90); button_dec->move(310,310); button_mul->resize(90,90); button_mul->move(10,410); button_div->resize(90,90); button_div->move(110,410); button_clear->resize(90,90); button_clear->move(210,410); button_equal->resize(90,90); button_equal->move(310,410); button_left->resize(90,90); button_left->move(410,110); button_right->resize(90,90); button_right->move(410,210); button_point->resize(90,90); button_point->move(410,310); button_delete->resize(90,90); button_delete->move(410,410); //連線、處理訊號,lambda表示式 connect(button_0,&QPushButton::clicked, [=]() { //button_0->setText("123"); s+="0"; text->setText(s); } ); connect(button_1,&QPushButton::clicked, [=]() { s+="1"; text->setText(s); } ); connect(button_2,&QPushButton::clicked, [=]() { s+="2"; text->setText(s); } ); connect(button_3,&QPushButton::clicked, [=]() { s+="3"; text->setText(s); } ); connect(button_4,&QPushButton::clicked, [=]() { s+="4"; text->setText(s); } ); connect(button_5,&QPushButton::clicked, [=]() { s+="5"; text->setText(s); } ); connect(button_6,&QPushButton::clicked, [=]() { s+="6"; text->setText(s); } ); connect(button_7,&QPushButton::clicked, [=]() { s+="7"; text->setText(s); } ); connect(button_8,&QPushButton::clicked, [=]() { s+="8"; text->setText(s); } ); connect(button_9,&QPushButton::clicked, [=]() { s+="9"; text->setText(s); } ); connect(button_add,&QPushButton::clicked, [=]() { s+="+"; text->setText(s); } ); connect(button_dec,&QPushButton::clicked, [=]() { s+="-"; text->setText(s); } ); connect(button_mul,&QPushButton::clicked, [=]() { s+="*"; text->setText(s); } ); connect(button_div,&QPushButton::clicked, [=]() { s+="/"; text->setText(s); } ); connect(button_clear,&QPushButton::clicked, [=]() { s=""; text->setText(s); } ); connect(button_left,&QPushButton::clicked, [=]() { s+="("; text->setText(s); } ); connect(button_right,&QPushButton::clicked, [=]() { s+=")"; text->setText(s); } ); connect(button_point,&QPushButton::clicked, [=]() { s+="."; text->setText(s); } ); connect(button_delete,&QPushButton::clicked, [=]() { s=s.left(s.length()-1); text->setText(s); } ); // connect(button_equal,&QPushButton::clicked, // this, // &MainWindow::calculate // ); connect(button_equal,&QPushButton::clicked, [=]() { MainWindow::calculate(); text->setText(s); } ); //槽函式,由於使用lambda表示式簡便書寫,多數實現 } MainWindow::~MainWindow() { } void MainWindow::calculate() { //qDebug() << "Ready"; //QString _s; //qDebug() << s[0]; _tNode Node[NUM_OF_NUMBER]; double num1=0; int len=s.length(); int i=0; //字串位置 int num_of_point=0; //小數點個數 int num_or_op=0; //浮點數和操作符的個數 int isfloat=0; //小數點 while(i<len){ if((s[i]>='0'&&s[i]<='9')){ if(!isfloat){ //整數部分 num1=num1*10+(s[i].toLatin1()-'0'); ++i; } else{ //小數部分 double per=1; for(int k=0;k<num_of_point;k++) per*=0.1; num1+=(s[i].toLatin1()-'0')*per; num_of_point++; ++i; } } else if(s[i].toLatin1()=='.'){ //讀到小數點 isfloat=1; num_of_point=1; i++; } else{ //讀到操作符 if(num1){ Node[num_or_op].flag=KIND_NUMBER; Node[num_or_op].num.a=num1; num1=0; ++num_or_op; isfloat=0; num_of_point=0; } Node[num_or_op].flag=KIND_OPERATOR; Node[num_or_op].num.op=s[i].toLatin1(); ++num_or_op; ++i; } } if(num1){ Node[num_or_op].flag=KIND_NUMBER; Node[num_or_op].num.a=num1; ++num_or_op; //qDebug() << num1; num1=0; } //qDebug() << num_or_op; // for(int i=0;i<=num_or_op;i++) // if(Node[i].flag) // qDebug() << Node[i].num.op; // else // qDebug() << Node[i].num.a; //以上是轉換 //以下是計算 QStack<_tNode> pNode; _tNode _Node[NUM_OF_NUMBER]; int j = 0; for(int i = 0; i < num_or_op;){ if(Node[i].flag){//符號 if(pNode.isEmpty()) pNode.push_back(Node[i++]); else{ _tNode tem=pNode.top(); int ret=process(tem.num.op,Node[i].num.op); switch (ret) { case -1: pNode.push_back(Node[i++]); break; case 1: _Node[j++]=pNode.top(); pNode.pop(); //pNode.push_back(Node[i]); break; default: pNode.pop(); i++; break; } } } else{ _Node[j++]=Node[i++]; } } for(;!pNode.isEmpty();){ _tNode tem=pNode.top(); if(tem.num.op != '('&& tem.num.op != ')') _Node[j++]=tem; pNode.pop(); } // for(int i=0;i<=j;i++) // if(_Node[i].flag) // qDebug() << _Node[i].num.op; // else // qDebug() << _Node[i].num.a; //具體計算過程: QStack<double> last; double d1,d2; for(int i = 0; i < j; i++){ if(_Node[i].flag){//操作符 d2=last.top(); last.pop(); d1=last.top(); last.pop(); switch (_Node[i].num.op) { case '+': d1+=d2; break; case '-': d1-=d2; break; case '*': d1*=d2; break; case '/': d1/=d2; break; default: break; } last.push_back(d1); } else{ last.push_back(_Node[i].num.a); } } qDebug() << d1; s += '='; s += QString::number(d1); } int MainWindow::process(char a, char b) { char aim[7][8] = { { ">><<<>>" },{ ">><<<>>" },{ ">>>><>>" },{ ">>>><>>" },{ "<<<<<=1" },{ ">>>>1>>" },{ "<<<<<1=" } }; char sta[7] = { '+','-','*','/','(',')','#' }; char _result; int i, pa, pb; for (i = 0; i<6; i++) { if (a == sta[i])pa = i; if (b == sta[i])pb = i; } _result = aim[pa][pb]; if (_result == '>')return 1; else if (_result == '<')return -1; else return 0; }