qt界面开发入门以及计算器制作
qt界面开发
这节内容不涉及qt的安装,安装请参考
【保姆级图文教程】最新Windows系统QT下载、安装、入门、配置VS Qt环境,图文详细、内容充实
视频学习请参考【QT快速入门 | 最简单最简洁的QT入门教程 | 嵌入式UI】
本内容也是对视频链接的总结,如有侵权立马删稿。
首先我们的目标是用qt制作一个这样的简易页面。
这个页面设计最关键的几个部分就是,打开UI窗口找到
用这两个标签即可
槽设计,槽设计主要是为了让模块可以链接到代码实现相应的功能。
查找使用函数时,选择帮助按钮。
刚开始你可能看不到索引,得在帮助H中找到索引并添加。
它其实就类似于man 2 的作用。
mainwindow.cpp中输入以下代码,即可制作一个打开窗口。输入notepad即可打开记事本。
QProcess *myProcess = new QProcess(parent);myProcess->start(program, arguments);
完整代码如下。
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_commitButton_clicked()
{// 获取lineedit数据QString program = ui->cmdlineEdit->text();// 创建process对象QProcess *myProcess = new QProcess(this);myProcess->start(program);
}
实现确定、取消、浏览三功能
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);// 连接信号与槽 谁发出信号 发出上面信号 谁处理信号 怎么处理connect(ui->cmdlineEdit,SIGNAL(returnPressed()),this,SLOT(on_commitButton_clicked()));connect(ui ->CancelButton,&QPushButton::clicked,this, &MainWindow::on_CancelButton_clicked);connect(ui ->browseButton,&QPushButton::clicked,[this](){QMessageBox::information(this,"信息","点击浏览");});}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_commitButton_clicked()
{// 获取lineedit数据QString program = ui->cmdlineEdit->text();// 创建process对象QProcess *myProcess = new QProcess(this);myProcess->start(program);
}void MainWindow::on_CancelButton_clicked()
{this -> close();
}
说实在的感觉还挺好玩的。
计算器制作
如图所示新建项目
选择第一个
选择qmake
我是直接默认
这里选择的是MinGW
以上默认即可。
页面字体设置
选中之后点击三个点点,设计字体。点大小也就是字体大小。
把最大最小都设置好就可以保证你的框都是统一的。
UI界面中将line Edit和Push Button 都放好。
要是觉得叉叉标识太小了,可以设置
计算器完整代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include "ui_mainwindow.h"
#include <QMainWindow>
#include <QStack>
#include <QString>
#include <QDebug> // 可选,用于调试
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_oneButton_clicked();void on_zeroButton_clicked();void on_threeButton_clicked();void on_leftButton_clicked();void on_rightButton_clicked();void on_fourButton_clicked();void on_fiveButton_clicked();void on_sixButton_clicked();void on_sevenButton_clicked();void on_eightButton_clicked();void on_nineButton_clicked();void on_addButton_clicked();void on_subButton_clicked();void on_mulButton_clicked();void on_divButton_clicked();void on_equalButton_clicked();void on_twoButton_clicked();void on_clearButton_clicked();void on_delButton_clicked();private:Ui::MainWindow *ui;QString expression;private:// 获取运算符优先级int getPriority(QChar op) {if (op == '+' || op == '-') return 1;if (op == '*' || op == '/') return 2;return 0; // 括号或其他}// 判断是否为运算符bool isOperator(QChar c) {return c == '+' || c == '-' || c == '*' || c == '/';}// 执行计算操作void calculate(QStack<double> &numStack, QStack<QChar> &opStack) {if (numStack.size() < 2 || opStack.isEmpty()) return;double right = numStack.pop();double left = numStack.pop();QChar op = opStack.pop();double result = 0;switch (op.toLatin1()) {case '+': result = left + right; break;case '-': result = left - right; break;case '*': result = left * right; break;case '/':if (qFuzzyIsNull(right)){ // 处理除以零的情况ui->mainlineEdit->setText("Error: Division by zero");numStack.push(0);return;} else {result = left / right;}break;}numStack.push(result);}
};#endif // MAINWINDOW_H
mainwindow.c
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow){ui->setupUi(this);this -> setMaximumSize(232,322);this -> setMaximumSize(232,322);this -> setWindowTitle("计算器");QFont f("Time New Roman",14);ui -> mainlineEdit->setFont(f);// 按钮上放图片QIcon con("D:\\VScode\\qt\\class_five\\calculator\\tt.jpg");ui->delButton->setIcon(con);//改变按钮的背景色ui->equalButton->setStyleSheet("background:green");}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_zeroButton_clicked()
{expression += "0";ui->mainlineEdit->setText(expression);
}void MainWindow::on_oneButton_clicked()
{expression += "1";ui->mainlineEdit->setText(expression);
}void MainWindow::on_twoButton_clicked()
{expression += "2";ui->mainlineEdit->setText(expression);
}void MainWindow::on_threeButton_clicked()
{expression += "3";ui->mainlineEdit->setText(expression);
}void MainWindow::on_fourButton_clicked()
{expression += "4";ui->mainlineEdit->setText(expression);
}void MainWindow::on_fiveButton_clicked()
{expression += "5";ui->mainlineEdit->setText(expression);
}void MainWindow::on_sixButton_clicked()
{expression += "6";ui->mainlineEdit->setText(expression);
}void MainWindow::on_sevenButton_clicked()
{expression += "7";ui->mainlineEdit->setText(expression);
}void MainWindow::on_eightButton_clicked()
{expression += "8";ui->mainlineEdit->setText(expression);
}void MainWindow::on_nineButton_clicked()
{expression += "9";ui->mainlineEdit->setText(expression);
}void MainWindow::on_addButton_clicked()
{expression += "+";ui->mainlineEdit->setText(expression);
}void MainWindow::on_subButton_clicked()
{expression += "-";ui->mainlineEdit->setText(expression);
}void MainWindow::on_mulButton_clicked()
{expression += "*";ui->mainlineEdit->setText(expression);
}void MainWindow::on_divButton_clicked()
{expression += "/";ui->mainlineEdit->setText(expression);
}void MainWindow::on_equalButton_clicked()
{if (expression.isEmpty()) {ui->mainlineEdit->setText("0");return; //立即结束函数执行}QStack<double> numStack; // 数字栈,容器顺序存放QStack<QChar> opStack; // 运算符栈int i = 0;int n = expression.length(); //记录整个字节长度while (i < n) //逐个读取{if (expression[i].isDigit() || expression[i] == '.') //是数字或者小数点{// 处理数字(包括小数)QString numStr;while (i < n && (expression[i].isDigit() || expression[i] == '.')){numStr.append(expression[i]); // 数字读取,切记碰到运算符会被打断i++;}bool ok;double num = numStr.toDouble(&ok); // 转换数据格式为double型if (ok){numStack.push(num); // 存入一次数值}} else if (expression[i] == '('){// 左括号直接入栈opStack.push(expression[i]);i++;} else if (expression[i] == ')'){// 遇到右括号,计算直到遇到左括号while (!opStack.isEmpty() && opStack.top() != '('){calculate(numStack, opStack); //没有左括号,直接计算}if (!opStack.isEmpty() && opStack.top() == '('){opStack.pop(); // 弹出左括号}i++;} else if (isOperator(expression[i])) // 如果当前字符是运算符{// 处理运算符优先级while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(expression[i])){ // 栈顶运算符和当前读取到的运算符的优先级// 只要栈顶运算符的优先级高于或等于当前运算符,就执行计算calculate(numStack, opStack);}opStack.push(expression[i]);i++;} else{i++; // 跳过空格等无效字符}}// 处理剩余的运算符while (!opStack.isEmpty()) {calculate(numStack, opStack);}// 显示结果if (!numStack.isEmpty()) {double result = numStack.top();ui->mainlineEdit->setText(QString::number(result, 'g', 10)); // 使用合适精度expression = QString::number(result); // 更新表达式,便于继续计算}
}void MainWindow::on_leftButton_clicked()
{expression += "(";ui->mainlineEdit->setText(expression);
}void MainWindow::on_rightButton_clicked()
{expression += ")";ui->mainlineEdit->setText(expression);
}void MainWindow::on_clearButton_clicked()
{expression.clear();ui->mainlineEdit->clear();}void MainWindow::on_delButton_clicked()
{expression.chop(1);ui->mainlineEdit->setText(expression);
}
我觉得代码中可能最难理解的部分就是,符号优先级判断了
也就是这一块
else if (isOperator(expression[i])) // 如果当前字符是运算符
{// 处理运算符优先级while (!opStack.isEmpty() && getPriority(opStack.top()) >= getPriority(expression[i])){ // 栈顶运算符和当前读取到的运算符的优先级// 只要栈顶运算符的优先级高于或等于当前运算符,就执行计算calculate(numStack, opStack);}opStack.push(expression[i]);i++;
}
结合例子讲一下,解析表达式 “3 + 5 * 2”
让我们通过一个简单的例子来可视化这个过程。假设表达式是 “3 + 5 * 2”,我们知道正确答案是 3 + (5 * 2) = 13,而不是 (3 + 5) * 2 = 16。
当前字符 | 动作 | 数字栈 (numStack) | 运算符栈 (opStack) |
---|---|---|---|
5 | 数字,压入数字栈 | [3, 5] | [+] |
* | 关键步骤:遇到 * | [3, 5] | [+] |
1. 进入 while循环 | 2. 检查条件:!opStack.isEmpty()-> 真 (栈有 +) | 3. 比较优先级:getPriority(‘+’)(1) >= getPriority(‘*’)(2)` -> 假 (1 >= 2 不成立) | 4. 因此,while循环条件不满足,跳出循环 |
将 *压入运算符栈 | [3, 5] | [+, *] | 5. 执行 opStack.push(‘*’) |
2 | 数字,压入数字栈 | [3, 5, 2] | [+, *] |
| 表达式读完,开始清理栈 | [3, 5, 2] | [+, *] |
while (!opStack.isEmpty())循环开始,
弹出 *和 5, 2,计算 5 * 2 = 10,结果压栈[3, 10][+]
弹出 +和 3, 10,计算 3 + 10 = 13,结果压栈[13][]
![]() | ![]() |
---|---|
![]() | ![]() |