QT入门_简易计算器的实现与遇到的问题汇总

目录

  • 效果图
  • 使用方法和功能
  • 代码
    • main.cpp
    • mainwindow.h
    • mainwindow.cpp
    • ui_mainwindow.h
  • 遇到的问题汇总
    • 自定义命名空间的相关问题
    • 关于隐式调用构造函数的问题
    • 关于on_pushButton_clicked()的默认connect

效果图

QT入门_简易计算器的实现与遇到的问题汇总_第1张图片

使用方法和功能

只有最基础的两个数加减乘除,没有清除键,使用Ui设计界面
点击数字在EditLine1中会显示,点击flag会使输入在EditLine1和3中切换,点击加减乘除会在2中显示
点击等于在前三个EditLine中都有数字/字符的情况下输出结果

代码

main.cpp

#include 
#include "mainwindow.h"

int main(int argc,char *argv[]){
     

    QApplication a(argc,argv);
    MainWindow w;

    w.show();
    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 


namespace Ui {
     
    class MainWindow;
}

class MainWindow : public QMainWindow
{
     
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    double num1 = -1;
    double num2 = -1;
    int flag;//用flag判断输入的是第几个数
    QString s1,s2,s3;
    QChar opt;

private:
    Ui::MainWindow *ui;

private slots:
    void on_btn0_clicked();
    void on_btn1_clicked();
    void on_btn2_clicked();
    void on_btn3_clicked();
    void on_btn4_clicked();
    void on_btn5_clicked();
    void on_btn6_clicked();
    void on_btn7_clicked();
    void on_btn8_clicked();
    void on_btn9_clicked();

    void on_btnpls_clicked();
    void on_btnmns_clicked();
    void on_btnmltpl_clicked();
    void on_btndvdd_clicked();
    void on_btnequal_clicked();
    void on_btnflag_clicked();
    void setBackgroundImage(QString path);

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "ui_mainwindow.h"
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent),ui(new Ui::MainWindow)
{
     
    flag = 1;
    ui->setupUi(this);
    s1 = "";
    s2 = "";
    s3 = "";
//实现连接函数
    connect(this->ui->btn0,SIGNAL(clicked(bool)),this,SLOT(on_btn0_clicked()));
    connect(this->ui->btn1,SIGNAL(clicked(bool)),this,SLOT(on_btn1_clicked()));
    connect(this->ui->btn2,SIGNAL(clicked(bool)),this,SLOT(on_btn2_clicked()));
    connect(this->ui->btn3,SIGNAL(clicked(bool)),this,SLOT(on_btn3_clicked()));
    connect(this->ui->btn4,SIGNAL(clicked(bool)),this,SLOT(on_btn4_clicked()));
    connect(this->ui->btn5,SIGNAL(clicked(bool)),this,SLOT(on_btn5_clicked()));
    connect(this->ui->btn6,SIGNAL(clicked(bool)),this,SLOT(on_btn6_clicked()));
    connect(this->ui->btn7,SIGNAL(clicked(bool)),this,SLOT(on_btn7_clicked()));
    connect(this->ui->btn8,SIGNAL(clicked(bool)),this,SLOT(on_btn8_clicked()));
    connect(this->ui->btn9,SIGNAL(clicked(bool)),this,SLOT(on_btn9_clicked()));
    connect(this->ui->btnpls,SIGNAL(clicked(bool)),this,SLOT(on_btnpls_clicked()));
    connect(this->ui->btnmns,SIGNAL(clicked(bool)),this,SLOT(on_btnmus_clicked()));
    connect(this->ui->btnmltpl,SIGNAL(clicked(bool)),this,SLOT(on_btnmltpl_clicked()));
    connect(this->ui->btndvdd,SIGNAL(clicked(bool)),this,SLOT(on_btndvdd_clicked()));
    connect(this->ui->btnequal,SIGNAL(clicked(bool)),this,SLOT(on_btnequal_clicked()));
//    connect(this->ui->btnflag,SIGNAL(clicked(bool)),this,SLOT(on_btnflag_clicked()));

    setWindowTitle("Calculator");
    setBackgroundImage(":/new/prefix1/image/monstercat.jpg");

}

//设置背景图片  path:图片路径
void MainWindow ::setBackgroundImage(QString path)
{
     
   QPixmap pixmap = QPixmap(path).scaled(this->size());
   QPalette palette(this->palette());
   palette.setBrush(QPalette::Background, QBrush(pixmap));
   this->setPalette(palette);
}

MainWindow::~MainWindow()
{
     
    delete ui;
}

//实现槽函数
void MainWindow::on_btn0_clicked(){
     
    if(flag==1){
     
        s1 ="0";
        num1 = 0.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="0";
        num2 = 0.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn1_clicked(){
     
    if(flag==1){
     
        s1 ="1";
        num1 = 1.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="1";
        num2 = 1.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn2_clicked(){
     
    if(flag==1){
     
        s1 ="2";
        num1 = 2.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="2";
        num2 = 2.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn3_clicked(){
     
    if(flag==1){
     
        s1 ="3";
        num1 = 3.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="3";
        num2 = 3.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn4_clicked(){
     
    if(flag==1){
     
        s1 ="4";
        num1 = 4.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="4";
        num2 = 4.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn5_clicked(){
     
    if(flag==1){
     
        s1 ="5";
        num1 = 5.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="5";
        num2 = 5.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn6_clicked(){
     
    if(flag==1){
     
        s1 ="6";
        num1 = 6.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="6";
        num2 = 6.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn7_clicked(){
     
    if(flag==1){
     
        s1 ="7";
        num1 = 7.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="7";
        num2 = 7.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn8_clicked(){
     
    if(flag==1){
     
        s1 ="8";
        num1 = 8.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="8";
        num2 = 8.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}
void MainWindow::on_btn9_clicked(){
     
    if(flag==1){
     
        s1 ="9";
        num1 = 9.0;
        this->ui->lineEdit_num1->setText(s1);
    }
    else if(flag ==2){
     
        s2 ="9";
        num2 = 9.0;
        this->ui->lineEdit_num2->setText(s2);
    }
}

void MainWindow::on_btnpls_clicked(){
     
    opt = '+';
    this->ui->lineEdit_operator->setText("+");
}
void MainWindow::on_btnmns_clicked(){
     
    opt = '-';
    this->ui->lineEdit_operator->setText("-");
}
void MainWindow::on_btnmltpl_clicked(){
     
    opt = '*';
    this->ui->lineEdit_operator->setText("*");
}
void MainWindow::on_btndvdd_clicked(){
     
    opt = '/';
    this->ui->lineEdit_operator->setText("/");
}
void MainWindow::on_btnflag_clicked(){
     
    if(flag == 1){
     
        flag = 2;
    }
    else if(flag == 2){
     
        flag = 1;
    }
//    flag = 2;
}

void MainWindow::on_btnequal_clicked(){
     
    if(num1!=-1&&num2!=-1&&opt!=NULL){
     
        if(opt == '+') s3 =QString("%1").arg(num1+num2);
        else if(opt == '-') s3 =QString("%1").arg(num1-num2);
        else if(opt == '*') s3 =QString("%1").arg(num1*num2);
        else if(opt == '/') s3 =QString("%1").arg(num1/num2);
        this->ui->lineEdit_result->setText(s3);
    }
}

ui_mainwindow.h

这里笔者直接用ui设计,头文件比较复杂而且比较长,故不粘贴源码
QT入门_简易计算器的实现与遇到的问题汇总_第2张图片

遇到的问题汇总

这里是笔者学习日志关于简易计算器实现的问题的汇总,原文链接:
QT学习日志(笔记/问题)(6.30-7.18持更)

自定义命名空间的相关问题

这串代码困扰了我好久
mainwindow.h:

namespace Ui {
     
    class MainWindow;
}

ui_mainwindow.h:

namespace Ui {
     
    class MainWindow: public Ui_MainWindow {
     };
} // namespace Ui

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent),ui(new Ui::MainWindow)
{
     
	......
}

疑问的解决参考:
①Qt Ui 头文件研究 (推荐这篇文章,讲得很好)
简单来说,命名空间的用处就是命名变量、类等,多次定义会报错,mainwindow.h中只是声明MainWindow类,ui_mainwindow.h中是在定义MainWindow类,关于命名空间的其他细节请参考上述文章
②MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)解析
至于为什么后面还要加上ui(new Ui::MainWindow),个人的理解是:本来这条语句是定义MainWindow的构造函数,“:”后面的不是类名后有参数说明它也不是继承关系,而是采用初始化列表构造函数。而由于在类外定义构造函数而直接用类中的成员变量会报错,所以采用:ui(new Ui::MainWindow)ui->setupUi(this)this->ui->btn0的方式来使用类的成员变量

(其实笔者当时理解不了是忘记这个使用初始化列表的构造函数的知识点了,哼唧唧.jpg)

书上的知识点:
在这里插入图片描述

关于隐式调用构造函数的问题

敲代码的时候:
有时程序运行不出正确结果,冥思苦想,却说这也不行?
有时候程序突然能运行出正确结果了,一脸懵逼,这怎么又可以?

又是这里:

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent),ui(new Ui::MainWindow)
{
     
	......
}

我定义的是有参构造函数吧

int main(int argc,char *argv[]){
     
    QApplication a(argc,argv);
    MainWindow w;
    w.show();
    return a.exec();
}

怎么一到主函数变成无参构造了?
本来头一天照着别人的写简易计算器都能运行出正确结果了,今天已检查又纳闷了,这都行?

其实是笔者c++基础不牢实

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

这是缺省的构造函数啦,忘记的可以回去翻课本了
另外关于explicit的用法:explicit关键字的作用

关于on_pushButton_clicked()的默认connect

昨天写计算器的时候遇到一个问题:
老感觉函数里的if 和 else if里的代码都执行了

void MainWindow::on_btnflag_clicked(){
     
    if(flag == 1){
     
        flag = 2;
    }
    else if(flag == 2){
     
        flag = 1;
    }
//    flag = 2;
}

(之前的写的槽函数也遇到了这样的问题,不过后面改掉了,留下了这一个)
我还问朋友,这啥机制啊,Qt里if 和else还有这种操作吗?
我一直很疑惑,思考过后觉得是这个函数运行了两次,但由于信号与槽学得并不好,对这种机制还不是很了解,这里就直接把代码改成了 flag = 2;也就是说flag按钮不能在两个lineEdit中切换了,一旦换到另一个就再不能回到之前那个了。修改过后发现计算器也能用,就没再追究
今天决定再看看这个问题(其实昨天也是因为不知道怎么搜)
搜了个关键字on_pushButton_clicked(),看了这篇博客:Qt on_pushButton_clicked()的用法,豁然开朗
其实也就是Qt Creater默认给你完成on_pushButton_clicked()的信号与槽连接函数,由于我再写了个connect函数,这个语句被执行两遍,就跟没执行一样了,把connect函数注释掉后,flag按钮恢复功能

你可能感兴趣的:(Qt,qt,c++,编程语言)