Qt 桌面计算器项目

一、项目概述

在学习 Qt 桌面开发的过程中,计算器项目是经典的入门实战项目,既能巩固 Qt 核心机制,又能快速实现可视化效果。本文将完整记录一款支持四则运算、括号运算、界面美化的 Qt 计算器项目,从 UI 设计、逻辑实现、问题排查到打包发布,全程可复现,适合 Qt 入门学习与面试项目展示。

技术栈

  • 开发语言:C++
  • 开发框架:Qt 5.8.0(Qt Widgets 模块)
  • 构建工具:qmake
  • 开发环境:Qt Creator
  • 核心技术:信号与槽、QString 字符串处理、UI 布局、QSS 样式美化、表达式解析

项目功能

  • 0-9 数字、小数点输入
  • 加减乘除四则运算、括号优先级运算
  • 清零、退格、等于计算功能
  • 现代化 UI 美化(圆角按钮、hover 效果、主题配色)
  • 窗口标题自定义、字体样式设置

项目展示


二、项目开发流程

1. 新建项目与 UI 设计

(1)新建 Qt Widgets 项目

打开 Qt Creator,选择「Application → Qt Widgets Application」,项目名命名为NiceCalculator,基类选择QWidget,完成项目创建。

(2)UI 界面布局

双击widget.ui进入 Qt Designer 设计界面,按以下步骤完成布局:

  1. 顶部添加 1 个QLineEdit作为输入显示框,设置objectNamelineEdit,勾选readOnly(只读,禁止手动输入),设置右对齐显示。
  2. 下方添加 19 个QPushButton,按计算器布局排列,按钮objectName统一规范命名:
    • 数字:btn0~btn9btnDot(小数点)
    • 运算符:btnAdd(+)、btnSub(-)、btnMul(*)、btnDiv(/)、btnLeft(()、btnRight())
    • 功能键:btnClear(清空)、btnDel(删除)、btnEqual(等于)
  3. 全选按钮,右键选择「Layout → Grid Layout」自动排版,选中整个窗口右键「Lay Out Vertically」,实现界面自适应。

2. 核心代码实现

(1)头文件widget.h

定义类、槽函数与成员变量,声明所有按钮的点击事件:

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QString>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

// 数字按钮槽函数
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_btnDot_clicked();

// 运算符按钮槽函数
    void on_btnAdd_clicked();
    void on_btnSub_clicked();
    void on_btnMul_clicked();
    void on_btnDiv_clicked();
    void on_btnLeft_clicked();
    void on_btnRight_clicked();

// 功能按钮槽函数
    void on_btnClear_clicked();
    void on_btnDel_clicked();
    void on_btnEqual_clicked();

private:
    Ui::Widget *ui;
    QString expression; // 存储用户输入的表达式
};

#endif // WIDGET_H
(2)源文件widget.cpp

实现按钮逻辑、界面初始化、表达式计算与 UI 美化:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QScriptEngine>
#include <QFont>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 窗口基础设置
    setWindowTitle("cmh计算器");
    setFixedSize(340, 460); // 固定窗口大小,禁止拉伸

    // 输入框字体设置
    QFont f("Microsoft YaHei", 22, QFont::Bold);
    ui->lineEdit->setFont(f);
    ui->lineEdit->setAlignment(Qt::AlignRight);

    // QSS全局样式美化
    this->setStyleSheet(R"(
        QWidget { background:#f5f7fa; }
        QLineEdit {
            border:none; border-radius:12px;
            padding:16px; background:#fff;
            margin-bottom:10px;
        }
        QPushButton {
            font-size:16px; border:none;
            border-radius:18px; background:#fff;
            min-height:45px;
        }
        QPushButton:hover { background:#e6e8ed; }

        QPushButton#btnClear,QPushButton#btnDel{
            background:#ff7878; color:white;
        }
        QPushButton#btnClear:hover,QPushButton#btnDel:hover{
            background:#ff5252;
        }

        QPushButton#btnEqual{
            background:#4285F4; color:white; font-weight:bold;
        }
        QPushButton#btnEqual:hover{
            background:#3367D6;
        }
    )");
}

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

// 数字按钮点击逻辑:拼接表达式
void Widget::on_btn0_clicked() { expression += "0"; ui->lineEdit->setText(expression); }
void Widget::on_btn1_clicked() { expression += "1"; ui->lineEdit->setText(expression); }
void Widget::on_btn2_clicked() { expression += "2"; ui->lineEdit->setText(expression); }
void Widget::on_btn3_clicked() { expression += "3"; ui->lineEdit->setText(expression); }
void Widget::on_btn4_clicked() { expression += "4"; ui->lineEdit->setText(expression); }
void Widget::on_btn5_clicked() { expression += "5"; ui->lineEdit->setText(expression); }
void Widget::on_btn6_clicked() { expression += "6"; ui->lineEdit->setText(expression); }
void Widget::on_btn7_clicked() { expression += "7"; ui->lineEdit->setText(expression); }
void Widget::on_btn8_clicked() { expression += "8"; ui->lineEdit->setText(expression); }
void Widget::on_btn9_clicked() { expression += "9"; ui->lineEdit->setText(expression); }
void Widget::on_btnDot_clicked() { expression += "."; ui->lineEdit->setText(expression); }

// 运算符按钮点击逻辑
void Widget::on_btnAdd_clicked() { expression += "+"; ui->lineEdit->setText(expression); }
void Widget::on_btnSub_clicked() { expression += "-"; ui->lineEdit->setText(expression); }
void Widget::on_btnMul_clicked() { expression += "*"; ui->lineEdit->setText(expression); }
void Widget::on_btnDiv_clicked() { expression += "/"; ui->lineEdit->setText(expression); }
void Widget::on_btnLeft_clicked() { expression += "("; ui->lineEdit->setText(expression); }
void Widget::on_btnRight_clicked() { expression += ")"; ui->lineEdit->setText(expression); }

// 清空按钮
void Widget::on_btnClear_clicked()
{
    expression.clear();
    ui->lineEdit->clear();
}

// 退格按钮
void Widget::on_btnDel_clicked()
{
    expression.chop(1);
    ui->lineEdit->setText(expression);
}

// 等于按钮:表达式计算
void Widget::on_btnEqual_clicked()
{
    QScriptEngine eng;
    QScriptValue val = eng.evaluate(expression);

    // 异常处理:表达式错误提示
    if(eng.hasUncaughtException()){
        ui->lineEdit->setText("Error");
        expression.clear();
    }else{
        // 显示结果,支持连续运算
        expression = val.toString();
        ui->lineEdit->setText(expression);
    }
}
(3)项目配置文件NiceCalculator.pro

添加script模块依赖,支持QScriptEngine表达式计算:

cpp 复制代码
QT       += core gui widgets script

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

三、项目难点与踩坑总结

1. 编译报错:'QString' does not name a type

问题原因 :头文件未包含 <QString>,或类名拼写错误(写成 Qstring 小写 s)。解决方案 :在 widget.h 中添加 #include <QString>,确保类名 QString 大小写正确。

2. 编译报错:QScriptEngine: No such file or directory

问题原因 :Qt 5 中 QScriptEngine 属于 script 模块,未在 .pro 文件中添加依赖。解决方案 :在 .pro 文件中添加 QT += script,执行 qmake 后重新编译。

3. 编译报错:stray '\357' in program

问题原因 :代码中混入了中文全角空格 / 不可见字符,导致编译器语法解析失败。解决方案:删除问题行,使用英文半角输入法重新输入,全程切换英文输入法编写代码。

4. 窗口标题修改不生效

问题原因 :代码中 setWindowTitle 优先级高于 UI 中的 windowTitle 属性,代码覆盖了 UI 设置。解决方案 :二选一修改,要么在 UI 中修改 windowTitle,要么在代码中修改,避免冲突。

5. 中文乱码问题

问题原因 :源文件编码非 UTF-8,导致中文显示乱码。解决方案 :在 Qt Creator 中设置文件编码为 UTF-8,代码中使用 QString::fromUtf8("中文") 包裹中文。


四、项目总结与收获

项目收获

  1. 掌握 Qt 核心机制:深入理解了 Qt 信号与槽、事件驱动编程、UI 布局等核心概念,熟悉了 Qt 项目的完整开发流程。
  2. 提升 C++ 编程能力:通过字符串处理、表达式计算、异常处理等逻辑,强化了 C++ 基础编程能力。
  3. 学会界面开发与美化:掌握了 Qt Designer 可视化布局、QSS 样式表美化、自定义图标等界面开发技巧。
  4. 培养问题排查能力:通过解决编译报错、逻辑 bug 等问题,提升了代码调试和问题排查能力。

后续优化方向

  • 支持负数运算,增加科学计算器功能(开方、平方、三角函数等)
  • 增加历史记录查询、表达式编辑功能
  • 适配深色模式、多主题切换
  • 打包为单文件 exe,提升分发便捷性
相关推荐
白杆杆红伞伞2 小时前
Qt Event
开发语言·qt
李昊哲小课2 小时前
Python办公自动化教程 - 第2章 单元格样式魔法 - 让表格变得美观专业
开发语言·python·excel·openpyxl
特立独行的猫a2 小时前
HarmonyOS鸿蒙PC的QT应用开发:QT项目运行原理与 EmbeddedUIExtensionAbility介绍
qt·华为·harmonyos·openharmony·鸿蒙pc
张健11564096482 小时前
QT创建线程
开发语言·qt
鲸渔2 小时前
【C++ 输入输出】cin、cout、cerr 与格式化输出
开发语言·c++·算法
3GPP仿真实验室2 小时前
【MATLAB源码】水声:时变信道估计仿真平台
开发语言·matlab
froginwe112 小时前
Eclipse 关闭项目详解
开发语言
wjs20242 小时前
《jQuery Validate》深度解析与应用指南
开发语言
森G2 小时前
51、Move方式创建线程---------多线程
c++·qt