QT计算器进阶功能实现:从界面布局到表达式解析

QT表格函数表达式计算工具 在公司产品中又新增了一个需求:需要在低代码工具平台中配置类似excel的函数表达式计算,如sum(单价*库存数量),其中“单价”和“库存数量”为该表格表头的标题,表示计算每一行的总金额然后对其求总和,之后显示到界面上显示。 阅读详情

1. 从零开始:搭建你的第一个QT计算器项目

很多朋友刚开始学QT的时候,总觉得界面编程有点抽象,信号槽机制也让人摸不着头脑。我自己当年也是这么过来的,对着文档看了半天,还是不知道从哪儿下手。后来我发现,做一个计算器,其实是理解QT核心机制最快、最直观的路径。它麻雀虽小,五脏俱全:UI布局、控件交互、事件处理、数据处理,全都能练到。今天,我就带你从零开始,一步步构建一个不仅支持加减乘除,还能处理平方、开方等科学运算的桌面计算器。我会把我在实际开发中踩过的坑、总结的技巧都揉碎了讲给你听,保证你跟着做一遍,就能对QT的编程模式有个扎实的理解。

我们这次的目标,不是做一个只能按“1+1=2”的玩具。我们要实现一个能处理连续表达式、即时反馈的“引擎”。比如,你可以输入“3+5*2”,计算器能正确算出13,而不是16。这背后就涉及到表达式解析的逻辑,这也是我们这次“进阶”的重点。别担心,我们不用什么高深的编译原理,就用最直白、最容易理解的字符串处理方法来实现。整个过程,我会假设你刚装好QT Creator,对C++有基础了解,但没怎么接触过QT。我们从创建项目开始,手把手走一遍。

首先,打开你的QT Creator,点击“新建项目”。这里有个小细节,我建议你选择“Application” -> “QT Widgets Application”。为什么选Widgets而不是QML?因为对于计算器这种逻辑驱动、控件固定的桌面应用,Widgets框架更成熟,资料更多,调试起来也更直观。项目名称和路径你随意,我习惯叫“AdvancedCalculator”。在“Base class”选择时,直接选QWidget就行,这是最通用的窗口基类。后面的页面一路“下一步”,直到完成。这样,你的项目骨架就搭好了,你会看到自动生成了 main.cpp, widget.h, widget.cpp, widget.ui 这几个核心文件。.ui文件就是我们的“画布”,接下来所有界面设计都在这里进行。

2. 界面布局的艺术:栅格化与控件管理

界面是用户的第一印象,一个布局混乱的计算器,功能再强也用着别扭。QT提供了一套非常强大的布局管理器(Layout),能自动处理控件的大小和位置,适应窗口缩放。对于计算器这种规整的按钮矩阵,栅格布局(Grid Layout) 是绝配。我刚开始学的时候,总喜欢用绝对坐标去摆控件,结果窗口一拉就全乱了,后来改用布局管理器,才体会到什么叫“一劳永逸”。

进入 widget.ui 文件,你会看到设计界面。首先,我们从左侧的“Containers”里拖一个 Widget 到中间的窗体上。这个Widget将作为所有数字和运算符按钮的容器。为什么单独用一个容器?好处是隔离和复用。我们可以单独对这个容器应用栅格布局,让里面的按钮排列整齐,并且这个容器作为一个整体,再和上方的显示框进行垂直布局,结构非常清晰。然后,从“Buttons”里拖拽 Push Button 到这个Widget容器里,我们需要数字0-9、小数点、加减乘除、等于、清除、平方、平方根等按钮。大概需要20个左右。

接下来是关键步骤:选中Widget容器里的所有按钮(可以按住Ctrl键多选),右键点击,选择“布局” -> “栅格布局”。QT会自动把这些按钮均匀地排列成一个矩阵。但自动排列可能不符合计算器的经典布局(比如“0”键通常占两格)。这时,你需要手动调整。选中某个按钮,在右下角的属性编辑器里,找到 layoutRowSpan 和 layoutColumnSpan 属性。比如,让“0”按钮横跨两列,就把它的 layoutColumnSpan 设为2。同理,把“=”按钮的 layoutRowSpan 设为2,让它占两行的高度。调整的过程就像玩拼图,多试试就顺手了。

按钮的文本显示也很重要。双击按钮就可以修改其 text 属性,比如改成“1”、“+”、“sqrt”等。但更重要的是修改它的 objectName 属性(在属性编辑器里)。默认的名字是 pushButton, pushButton_2 这种,完全没法记。我强烈建议你改成有意义的名称,比如 btnNum1, btnPlus, btnSqrt。这样在后面写代码关联信号槽时,一眼就知道哪个按钮对应哪个功能,极大减少出错概率。最后,从“Display Widgets”里拖两个 Line Edit 到窗体上,放在Widget容器的上方。这两个一个用作输入表达式显示(我命名为 lineEditInput),一个用作结果输出显示(命名为 lineEditOutput)。它们不要放进那个Widget容器里。现在,选中整个窗体(或者选中所有控件,包括两个LineEdit和那个Widget容器),应用一个 垂直布局(Vertical Layout)。这样,无论窗口怎么拉,所有元素都会保持相对位置和比例,非常美观。

3. 信号与槽:让按钮“活”起来的魔法

界面摆好了,但点按钮还没反应。这就是QT的核心机制——信号与槽(Signals & Slots) 要登场了。你可以把它理解成一个事件广播和订阅系统。按钮被点击了(发出“clicked()”信号),我们写一个函数(槽函数)来响应这个事件。把它们连接(connect)起来,魔法就发生了。原始文章里用了老式的 SIGNAL() 和 SLOT() 宏来连接,这在QT5和QT6里虽然还能用,但我更推荐使用新式的语法,它能在编译时检查类型,更安全,写起来也更简洁。

我们先在头文件 widget.h 里声明槽函数。打开 widget.h,在 private slots: 区域(如果没有就自己加一行)添加函数声明。注意,命名可以随意,但为了清晰,我习惯用 on_控件对象名_clicked() 的格式,这样一看就知道是哪个按钮的响应函数。

private slots:
    void on_btnNum1_clicked();
    void on_btnNum2_clicked();
    // ... 其他数字按钮
    void on_btnPlus_clicked();
    void on_btnMinus_clicked();
    void on_btnMultiply_clicked();
    void on_btnDivide_clicked();
    void on_btnEquals_clicked();
    void on_btnClear_clicked();
    void on_btnSqrt_clicked();
    void on_btnSquare_clicked();
    // ... 其他功能按钮

然后,在 widget.cpp 的构造函数里,进行信号与槽的连接。新式语法是这样的:

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

    // 连接数字按钮
    connect(ui->btnNum1, &QPushButton::clicked, this, &Widget::on_btnNum1_clicked);
    connect(ui->btnNum2, &QPushButton::clicked, this, &Widget::on_btnNum2_clicked);
    // ... 连接其他按钮

    // 连接运算符按钮
    connect(ui->btnPlus, &QPushButton::clicked, this, &Widget::on_btnPlus_clicked);
    // ... 以此类推
}

这种 &类名::信号 和 &类名::槽函数 的写法,是不是比老式的字符串宏清晰多了?而且如果你写错了函数名或类型,编译器会直接报错,而不是等到运行时才莫名其妙地没反应。这是我在调试时总结的血泪经验,一定要用新式连接。接下来,我们去实现这些槽函数。对于数字、小数点、运算符按钮,它们的逻辑很简单:把对应的字符追加到输入框(lineEditInput)的文本末尾。

void Widget::on_btnNum1_clicked()
{
    ui->lineEditInput->insert("1"); // insert会在光标处插入
    // 或者用 ui->lineEditInput->setText(ui->lineEditInput->text() + "1");
}

这里有个小技巧:insert() 是在当前光标位置插入文本,而 setText() 是替换全部文本。对于连续输入,insert() 更符合直觉,因为它能保持光标位置。你可以先简单实现,等所有功能都跑通后,再考虑优化光标逻辑。清除按钮(C或AC)的实现也很简单,就是清空输入输出框:ui->lineEditInput->clear(); ui->lineEditOutput->clear();。这样,一个能输入、能显示的架子就搭起来了。但光能输入不行,我们得让它能计算。

3.1 实现单步运算的陷阱

原始文章里的计算逻辑,是在等号按钮的槽函数里,用一堆 if 判断输入字符串里包含哪个运算符(如 indexOf("+")),然后进行分割计算。这个方法对于“A+B”这种单次运算是可行的。但它有一个致命缺陷:无法处理运算符优先级,也无法处理连续运算。比如输入“3+52”,它会先找到“+”,然后计算“3+5=8”,再乘以2吗?不会。因为它的逻辑是“找到第一个运算符就计算”,所以它会错误地计算“3+52”吗?实际上,由于它只处理第一个找到的运算符,并且只取运算符左右两边的字符串,对于“3+52”,它找到“+”,左边是“3”,右边是“52”,但 toDouble() 转换“5*2”会失败(返回0),导致结果错误。更别提连续输入“3+4-1”了。

所以,我们必须升级我们的计算核心,从“单步运算”进化到“表达式解析”。这听起来高大上,其实我们完全可以自己实现一个简化版。我们的目标是:能正确计算包含加减乘除、括号(可选)、平方、开方的表达式,并遵守先乘除后加减的优先级。

4. 表达式解析引擎:自己动手实现计算逻辑

表达式解析,说白了就是把用户输入的字符串(比如“3+5*2”),翻译成计算机能顺序执行的一系列运算。我们不做复杂的语法树,用一个相对取巧但足够有效的方法:双栈法。这个方法在《算法导论》里也有提到,特别适合带优先级的四则运算。我把它简化了一下,用计算器能理解的步骤来讲。

核心思想是准备两个栈:一个叫 操作数栈,专门存数字;一个叫 运算符栈,专门存加减乘除这些运算符号。我们从左到右扫描表达式字符串,遇到数字就压入操作数栈,遇到运算符就比较它和运算符栈栈顶元素的优先级。如果新运算符优先级更高,就压栈;如果更低或相等,就先从栈里弹出之前的运算符和操作数进行计算,把结果压回操作数栈,然后再处理新运算符。扫描完后,再把栈里剩下的运算依次弹出计算,最后操作数栈里剩下的那个数,就是结果。

为了支持平方(^2)和开方(sqrt)这种一元运算符(它们只对一个数进行操作),我们需要稍微调整一下逻辑。我建议在扫描前,先对表达式进行预处理,把这些特殊函数转换成标准运算符,或者单独处理。比如,把“4^2”转换成“4*4”,把“sqrt(9)”转换成对9进行开方运算。但为了保持代码清晰,我们可以在扫描过程中单独识别它们。

下面,我给出一个简化版本的核心解析函数 calculateExpression 的框架。它不处理括号,但能处理加减乘除和简单的平方、开方(我们约定平方用^2表示,开方用sqrt前缀表示,如sqrt9)。

double Widget::calculateExpression(const QString &expr)
{
    QStack<double> numStack; // 操作数栈
    QStack<QChar> opStack;   // 运算符栈
    QString number; // 用于临时拼接多位数

    // 定义优先级
    auto precedence = [](QChar op) -> int {
        if (op == '+' || op == '-') return 1;
        if (op == '*' || op == '/') return 2;
        return 0;
    };

    // 执行一次计算
    auto applyOperation = [&]() {
        if (numStack.size() < 2 || opStack.isEmpty()) return;
        double b = numStack.pop();
        double a = numStack.pop();
        QChar op = opStack.pop();
        double result = 0;
        switch (op.unicode()) {
            case '+': result = a + b; break;
            case '-': result = a - b; break;
            case '*': result = a * b; break;
            case '/': result = b != 0 ? a / b : 0; break; // 处理除零
            default: break;
        }
        numStack.push(result);
    };

    for (int i = 0; i < expr.length(); ++i) {
        QChar ch = expr[i];

        // 如果是数字或小数点,拼接到当前数字字符串
        if (ch.isDigit() || ch == '.') {
            number.append(ch);
        }
        // 如果是运算符
        else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
            if (!number.isEmpty()) {
                numStack.push(number.toDouble());
                number.clear();
            }
            // 处理负号作为一元运算符的情况(比如 -5)
            if (ch == '-' && (i == 0 || expr[i-1] == '(' || isOperator(expr[i-1]))) {
                // 这是一个负号,不是减号,我们简单处理,先压入0
                numStack.push(0);
                opStack.push('-'); // 实际上应该特殊标记,这里简化
            } else {
                // 比较优先级
                while (!opStack.isEmpty() && precedence(opStack.top()) >= precedence(ch)) {
                    applyOperation();
                }
                opStack.push(ch);
            }
        }
        // 这里可以添加对'^'和'sqrt'的识别和处理逻辑
    }

    // 处理最后一个数字
    if (!number.isEmpty()) {
        numStack.push(number.toDouble());
    }

    // 清空运算符栈
    while (!opStack.isEmpty()) {
        applyOperation();
    }

    return numStack.isEmpty() ? 0 : numStack.top();
}

这个函数是一个骨架,它展示了双栈法的流程。你需要完善它,比如添加对平方、开方的识别(可以在扫描到^或s时,向前或向后查看字符)。同时,这个函数没有处理表达式字符串中可能存在的空格,也没有做严格的错误检查(比如两个小数点、运算符不合法等)。在实际项目中,你需要添加这些健壮性处理。但作为入门,这个框架已经能帮你理解表达式解析的核心了。然后,在等号按钮的槽函数里,不再是一堆if-else,而是调用这个解析函数:

void Widget::on_btnEquals_clicked()
{
    QString expr = ui->lineEditInput->text();
    if (expr.isEmpty()) return;

    double result = calculateExpression(expr);
    ui->lineEditOutput->setText(QString::number(result));
}

4.1 处理平方与开方运算

平方和开方是一元运算符,它们只作用于一个数字。我们可以在表达式扫描过程中,当识别到“^2”时,就知道前面的数字需要平方。一个简单的办法是:在扫描完表达式字符串后,或者在进行双栈计算前,先对字符串进行预处理。例如,遍历字符串,找到“^2”,然后将其前面的数字提取出来,计算平方,再用结果替换掉“数字^2”这部分。开方处理类似,识别“sqrt”,然后提取后面的数字。

但更优雅的方式,是把它们也当作运算符,并入我们的双栈逻辑,只是它们的优先级最高,且是右结合的(先算平方再算乘除)。这需要扩展我们的运算符栈,使其能存储不同类型的操作(二元运算符如加减,一元运算符如平方)。对于初学者,我建议先用预处理的方法,虽然不够通用,但容易理解和实现。等双栈法玩熟了,再尝试扩展支持一元运算符。

QString preprocessExpression(QString expr) {
    // 处理平方: 将 "数字^2" 替换为 "数字*数字"
    QRegularExpression squareRegex("(\\d+(?:\\.\\d+)?)\\^2");
    expr.replace(squareRegex, "(\\1*\\1)");

    // 处理开方: 将 "sqrt数字" 替换为 "sqrt(数字)" 然后计算,这里简化处理
    // 更严谨的做法是在解析时单独处理
    // 我们可以先标记,比如替换为"$数字",然后在calculateExpression里识别'$'
    QRegularExpression sqrtRegex("sqrt(\\d+(?:\\.\\d+)?)");
    expr.replace(sqrtRegex, "$\1"); // 用$作为开方标记
    return expr;
}

然后在 calculateExpression 函数里,当遇到$字符时,就知道下一个数字(或从栈顶弹出)需要做开方运算。这样,我们就把特殊函数转化成了解析引擎能理解的“标记”。

5. 功能完善与用户体验打磨

基础的计算逻辑实现后,我们的计算器已经能处理不少表达式了。但一个用起来舒服的计算器,还需要很多细节打磨。比如,连续计算功能。通常,按下等号得出结果后,再按运算符,应该以上次的结果作为第一个操作数开始新的计算。这需要我们在类里添加一个成员变量,比如 lastResult,来记录上一次的计算结果。当按下等号后,不仅显示结果,也把结果存入 lastResult。当用户紧接着按运算符时,判断输入框是否为空,如果为空,就把 lastResult 作为表达式开头显示在输入框。

错误处理也至关重要。用户可能会输入“1/0”、“3++5”这样的非法表达式。我们的解析函数需要能够检测这些情况,并给出友好的提示,而不是直接崩溃或者输出一个无意义的值(如inf)。我们可以在 calculateExpression 函数中,在除法操作前判断除数是否为零,在运算符栈操作时检查操作数数量是否匹配。一旦发现错误,就抛出一个异常(或者返回一个特殊值),然后在界面上显示“错误”或“非法输入”。

double Widget::calculateExpression(const QString &expr)
{
    // ... 前面的代码 ...
    auto applyOperation = [&]() {
        if (numStack.size() < 2 || opStack.isEmpty()) return;
        double b = numStack.pop();
        double a = numStack.pop();
        QChar op = opStack.pop();
        double result = 0;
        switch (op.unicode()) {
            case '+': result = a + b; break;
            case '-': result = a - b; break;
            case '*': result = a * b; break;
            case '/':
                if (qFuzzyIsNull(b)) { // 判断b是否接近0
                    // 处理除零错误
                    throw std::runtime_error("Division by zero");
                }
                result = a / b;
                break;
            default: break;
        }
        numStack.push(result);
    };
    // ... 后面的代码 ...
    try {
        // 整个解析计算过程放在try块里
        // ...
    } catch (const std::exception &e) {
        // 在界面上显示错误信息,例如:
        ui->lineEditOutput->setText("错误: " + QString(e.what()));
        return 0.0;
    }
}

此外,键盘支持也是一个提升体验的点。我们可以重写窗口的 keyPressEvent 函数,监听键盘事件,将数字键、回车键(作为等号)、退格键(作为删除)等映射到对应的按钮点击事件上。这样用户就可以用键盘快速输入,效率倍增。

void Widget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
        case Qt::Key_0: on_btnNum0_clicked(); break;
        case Qt::Key_1: on_btnNum1_clicked(); break;
        // ... 其他数字键
        case Qt::Key_Plus: on_btnPlus_clicked(); break;
        case Qt::Key_Minus: on_btnMinus_clicked(); break;
        case Qt::Key_Asterisk: on_btnMultiply_clicked(); break;
        case Qt::Key_Slash: on_btnDivide_clicked(); break;
        case Qt::Key_Enter:
        case Qt::Key_Return: on_btnEquals_clicked(); break;
        case Qt::Key_Backspace: on_btnBackspace_clicked(); break; // 实现一个退格按钮
        case Qt::Key_Escape: on_btnClear_clicked(); break;
        default: QWidget::keyPressEvent(event); // 其他按键交给父类处理
    }
}

最后,别忘了美化界面。在构造函数里,我们可以用样式表(QSS)给按钮和输入框加点颜色、圆角、悬停效果,让计算器看起来更现代。比如:

this->setStyleSheet(
    "QPushButton {"
    "   font-size: 20px;"
    "   border: 2px solid #888;"
    "   border-radius: 10px;"
    "   background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #f6f7fa, stop:1 #dadbde);"
    "}"
    "QPushButton:hover {"
    "   background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #dadbde, stop:1 #f6f7fa);"
    "}"
    "QPushButton:pressed {"
    "   background-color: #ccc;"
    "}"
    "QLineEdit {"
    "   font-size: 24px;"
    "   border: 2px solid #aaa;"
    "   border-radius: 5px;"
    "   padding: 5px;"
    "}"
);

这些细节的打磨,会让你的计算器从“能用”变成“好用”。我自己在项目收尾阶段,总会花不少时间在这些用户体验的优化上,因为这才是区分普通程序和优秀程序的地方。代码写到这里,你已经拥有了一个功能相当完整的QT计算器。它不仅界面美观、布局合理,而且内核具备表达式解析能力,能处理优先级和连续运算,还有基本的错误处理和键盘支持。你可以以此为起点,继续添加更多功能,比如历史记录、内存存储、三角函数、括号支持等。每添加一个新功能,都是对QT和C++编程的一次深入练习。最重要的是,通过这个完整的项目,你已经把QT的核心概念——窗口、控件、布局、信号槽、事件处理——都亲手实践了一遍,这个经验比看十遍教程都来得实在。

C++与Qt开发科学计算器:从表达式解析到界面设计的完整实践 表达式解析是计算机科学中的基础概念,它涉及将人类可读的数学表达式转换为计算机可执行的结构。其核心原理通常包括词法分析、语法分析和求值三个阶段,其中调度场算法用于将中缀表达式转换为后缀表达式(逆波兰表示法),再利用栈数据结构高效求值。这项技术的价值在于它是编译器、解释器及各类计算工具(如科学计算器)的基石,能处理复杂运算符优先级和函数嵌套。在工程实践中,结合C++的高效运算能力和Qt框架的跨平台GUI特性,可以构建出功能完整、性能优异的桌面应用程序。本文以开发一个科学计算器为例,详细阐述了如何解决开发中常见的 阅读详情

相关推荐

【Qt】从零开始构建一个科学计算器:功能扩展与界面优化

本文详细介绍了如何使用Qt框架从零开始构建一个功能丰富的科学计算器,涵盖界面设计优化、核心计算功能实现以及高级功能扩展。通过分层架构设计和QSS样式表应用,开发者可以创建用户友好的科学计算器,支持三角函数、对数运算等复杂功能。文章还提供了调试技巧和性能优化建议,帮助开发者提升Qt GUI开发技能。

weixin_33737774的博客 395

Qt解析四则运算表达式

利用Qt的QString和QStringList进行的简单的表达式解析,不带括号,可以是小数。double MainWindow::calculate(QString str) { //利用递归去掉所有的加号 if(str.indexOf("+") != -1) { int i=str.indexOf("+"); return calculat

be_quiet_endeavor的博客 2188

C++桌面计算器开发实战:从表达式解析到Qt GUI实现

表达式解析是编译器与解释器的核心技术之一,其核心原理是将人类易读的中缀表达式转换为计算机高效处理的后缀表达式(逆波兰表达式),并利用栈结构进行求值。这项技术是实现各类计算工具、脚本引擎乃至编程语言解释器的基石,具有极高的工程实践价值。在桌面应用开发场景中,结合C++的高效性与Qt框架的跨平台能力,开发者可以构建出功能强大、性能优异的图形化计算工具。本文将以一个完整的桌面计算器项目为例,深入探讨如何运用调度场算法实现表达式解析,并基于模型-视图-控制器(MVC)架构,使用Qt的信号与槽机制,将核心计算引擎与图

weixin_32349093的博客 277

QT核心模块源码解析:数据绑定与表达式

数据绑定的基本概念数据绑定的基本概念数据绑定是Qt框架中的一个核心概念,它允许开发者在用户界面(UI)元素和数据模型之间建立一种连接。通过数据绑定,可以自动地同步UI元素的状态和数据模型的状态,从而实现声明式的用户界面开发。在Qt中,数据绑定主要通过QObject类和一系列的元对象系统来实现。数据绑定的目的数据绑定的主要目的是为了提高开发效率,减少重复的代码编写。在传统的编程模式中,开发者需要手动地管理UI元素的状态变化,这通常涉及到一系列的检测、更新和事件处理。

QT性能优化QT原理源码QT界面美化 1735

Qt框架实现基础计算器应用指南

随着计算机技术的迅猛发展,图形用户界面(GUI)程序已成为现代软件应用不可或缺的一部分。Qt,作为一个跨平台的应用程序和用户界面框架,被广泛应用于开发桌面、嵌入式和移动应用。开发一个Qt简单计算器不仅能够让我们熟悉Qt的基本操作和编程模式,而且还能够掌握图形用户界面设计、事件处理和表达式解析等关键概念。Qt框架为开发者提供了丰富的核心组件,这些组件可以被分为几个大类:基本工具类、图形和图像类、输入输出类、数据库类、网络类、多线程类、国际化类等。

weixin_42506884的博客 982

基于Qt Widgets的计算器实战:从界面搭建到表达式解析与打包发布

在桌面应用开发中,界面与逻辑分层是提升代码可维护性的关键实践。Qt 作为跨平台 C++ 框架,其 Widgets 模块与信号槽机制为事件驱动型工具类应用提供了高效解决方案。本文从一个可正常运算、支持括号与异常处理的 Qt 计算器项目切入,完整复盘了从界面布局(QGridLayout)、按钮事件绑定(Lambda 表达式)、中缀转后缀表达式解析(调度场算法)到安全求值的全链路实现细节。同时涵盖 QSS 样式定制、键盘快捷键支持、科学函数扩展及 QCustomPlot 函数图像绘制等进阶玩法。针对 Window

weixin_28840143的博客 316

Qt 正则表达式介绍 QRegExp的使用

#include "widget.h" #include "ui_widget.h" #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); QRegExp rx("^\\d\\d?$"); // 两个字符都必须为数字,第二个字符可以没有 qDebug() <&

超级大洋葱的博客 4678

Qt 科学计算器 使用后缀表达式解析

Qt制作的科学计算器,使用后缀表达式进行解析,例如输入12-5*2,答案是2,支持大于、大于等于、小于、小于等于、不等于、等于、与、或、非、阶乘、取模、括号等运算,源码结构清晰,支持增加自己想要的其他运算符。

Qt实现简易计算器

最近没事在学习Qt,做了一个简易计算器的小设计。记录在此,方便大家,也方便自己。 一、整体方案设计 本设计总体可分为两个部分,界面设计部分和内部逻辑部分。下面分别进行讲解。 二、界面设计部分: 界面设计入上图所示一些按钮和一个QLineEdit(用于输入数字和显示结果)和QLabel(用于显示运算表达式)。 本部分主要是采用界面设计师(直接拖拽设计)和代码设计部分。其中代码设计部分主要是为了完成...

xiaopan的博客 3万+

基于Cadence IC617的共源级放大器设计:从直流到交流的virtuoso仿真实践

本文详细介绍了使用Cadence IC617的Virtuoso平台进行共源级放大器设计的完整仿真流程。从电路图绘制、直流工作点分析,到负载电阻RD的参数扫描及其对增益和带宽的影响,再到交流小信号频率响应仿真,提供了从理论到实践的全面指导,帮助初学者掌握模拟集成电路设计的核心仿真技能。

jj890的博客 480

Android逆向分析

Android 逆向开发是指对已发布的 Android 应用进行分析和破解,以了解应用程序的内部工作原理,获取应用程序的敏感信息,或者修改应用程序的行为。Android应用 Java编写的,利用Android SDK编译代码,并并且把所有的数据和资源文件打包成一个APK(Android Package)文件这是一个后缀名为.apk的压缩文件,apk文件中包含了一个Anddroid应用程序的所有内容,是Android平台用于安装应用程序的文件。

qq_51598534的博客 6294

Qt实现的计算器

使用Qt实现一个计算器

YG爱木木 9632

STM407ZET6+OV5640调试心得

最近一个项目用了STMF407ZET6 +OV5640,调试了好几天做些总结; STMF407ZET6 开发板用的是正点原子的开发板,OV5640摄像头用的是秉火摄像头; 这其中有一个大坑,开发板的DCMI接口跟摄像头的接口不一样,要重新用杜邦线进行连接; 本人是在正点原子的“”15,ATK-OV5640摄像头模块“”源码上进行修改的。

kingseacjh的专栏 8326

qt界面开发入门以及计算器制作

本文介绍了Qt界面开发的基础知识,重点讲解了如何创建简单UI界面并实现功能交互。主要内容包括: Qt界面设计方法,使用标签和按钮控件 槽机制设计,实现按钮与代码功能的连接 使用QProcess类执行外部程序(如记事本) 计算器项目开发全过程: 新建项目配置 界面布局设计 字体和大小设置 按钮功能实现 提供了完整的代码示例,包括命令行执行器和简易计算器 文章还推荐了Qt安装教程和学习资源,适合Qt初学者快速入门界面开发。

weixin_52531699的博客 727

HCIP-Cloud Service DevOps Engineer V2.0 华为认证云服务 DevOps高级工程师 章节测试题+结课测试题(模拟考试题)汇总

本文为HCIP-Cloud Service DevOps Engineer V2.0 华为认证云服务DevOps高级工程师 在线课程中所有章节测试以及结课测试(HCIP-Cloud Service DevOps Engineer模拟考试)习题和答案

gaogao0305的博客 2269

Netty UDP

UDP是一种无连接的协议,它并不在通信双方之间建立连接,而是直接将数据包从发送端发送到接收端。UDP不保证数据包的可靠传输,也不保证数据包的顺序,因此其传输速度通常比TCP快,且系统开销较小。然而,这也意味着UDP在某些情况下可能会丢失数据包或数据包到达的顺序错乱。

王小工小工历程 2028

Qt计算器开发实战:从界面布局到核心逻辑的完整实现

图形用户界面(GUI)开发是软件工程中的重要领域,其核心在于将用户交互与后台逻辑高效解耦。Qt框架通过信号与槽机制实现了这一目标,该机制允许对象间进行松耦合通信,是Qt编程的基石。在工程实践中,掌握界面布局管理(如QGridLayout)和控件(如QPushButton、QLineEdit)的运用,是构建直观、响应式应用的关键。这些技术对于开发需要精确用户输入和即时反馈的工具(如计算器、数据仪表盘)具有极高价值。本文以开发一个功能完备的Qt计算器为例,深入探讨了如何运用信号与槽、状态机管理以及QSS样式表等

weixin_34090562的博客 393

innovus中如何设置cts参数

上面是设置cts的一般设置,如果需要对某些skew group或者某些clock tree设置不一样的参数,如需要对clk1这个clock设置不一样的inverter,可以使用。需要查询已经设置过的ccopt参数,可以使用get_ccopt_property去查询,方法和set_ccopt_property一致。言归正传,cts的设置命令是set_ccopt_property,获取命令是get_ccopt_property。另外,set_ccopt_property提供一套命令查询方法。

芯冰乐 548

Qt计算器开发:从零实现四则运算

Qt 作为跨平台的 C++ 图形界面开发框架,凭借其简洁的 API 和强大的信号槽机制,非常适合开发桌面应用。本文将手把手教你实现一个具备基础四则运算(加减乘除)、清空、退格功能的计算器,涵盖 Qt 界面布局、样式美化、信号槽绑定、表达式解析等核心知识点。

Aichirou3的博客 982

浏览器主页被2345劫持简单处理方法

本人比较常用的浏览器是IE和Chrome IE: 将网址修改为https://www.baidu.com 应用-确定-重新打开IE浏览器 或者win+r运行regedit打开注册表找到这个值   HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main下  和HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Main这个下面的StartPage ...

A soul tortured by desire 2万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Vs+Qt简单计算器设计流程(含运行截图)

Vs2019与Qt实现简单计算机

p3116002589的博客 3589

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

QT实现一个简单的计算器

通过本教程,我们成功实现了一个简单的计算器,支持基本的四则运算(加、减、乘、除)、括号运算、错误处理等功能。Qt 提供了丰富的控件和功能,使得我们可以轻松实现一个现代化的桌面应用程序。希望你通过本教程学到了 Qt 的基本用法,并能在此基础上进行更复杂的项目开发。如果你有任何问题,欢迎在评论区留言或者联系我。

weixin_63978486的博客 1153

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

QT开发之简易计算器

本文介绍了使用Qt框架开发简易计算器的全过程。项目基于QtWidgets和C++实现,支持基本四则运算,包含清晰的UI界面和完整的计算逻辑。文章详细说明了开发环境(Qt6.9.1)、项目结构、代码框架(包括主程序入口、计算器类定义和UI设计),重点解析了核心计算算法的栈实现方法。项目采用CMake构建,适合Qt初学者学习参考。最后提出了优化方向:支持浮点运算、增强错误处理、添加历史记录和完善高级运算功能。该计算器项目完整展示了Qt应用开发的基本流程,为后续功能扩展奠定了基础。

IKUN2333的博客 1236

Qt简易计算器的代码实现

大二用qt写的简易计算机,已经修改完bug,请放心食用 输入的时候一定用按钮,不要直接在文本框中输入 在qt中新建这几个文件,运行就OK了 main.cpp #include "calculator.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(...

zycxnanwang的博客 4万+
上一篇: 【安路科技FPGA实战】从零搭建开发环境到流水灯仿真(TD软件+Vivado)
下一篇: Tesla V100 Windows 部署实战:从驱动安装到模式切换的避坑指南
java5
博客等级 码龄22年 85粉丝 2103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值